main.c - gnuskii - GNUSki improved for ascii skiing experience.
(HTM) git clone git://bitreich.org/gnuskii git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/gnuskii
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) Tags
(DIR) README
(DIR) LICENSE
---
main.c (5070B)
---
1 /* GNUSki - a clone of the old game Skifree where you race downhill
2 avoiding rocks and trees and try to score points by doing some
3 tricks.
4 Copyright (C) 2007 Rudolf Olah
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include "objects.h"
22 #include <stdlib.h>
23 #include <time.h>
24 #include <stdio.h>
25 #include <unistd.h>
26 #include <ncurses.h>
27
28 #define MAX_OBJECTS 128
29
30 int main (int argc, char* argv[])
31 {
32 const long fps = argc != 2 ? 20l : strtol(argv[1], NULL, 10);
33 struct Object player, objects[MAX_OBJECTS];
34 unsigned int c = 0, i = 0, maxRows, maxCols, score = 0,
35 distance = 0, speed = 2, style = 0, frame_counter = 0;
36 enum mode {loop, lose, win} state = loop;
37 char facing[2] = {'s', 'n'}; /* Player facing, object facing */
38
39 srand ((unsigned)time (NULL)); /* Seed random-number generator */
40 initscr (); /* Start ncurses */
41 cbreak (); /* Allow control breaks (Ctrl+C) */
42 noecho (); /* Don't echo characters to screen */
43 keypad (stdscr, true); /* Allow cursor key usage */
44 curs_set (0); /* Hide the cursor */
45 getmaxyx (stdscr, maxRows, maxCols); /* Get coordinates of the terminal */
46 setupColors ();
47
48 /* Create objects */
49 player = makeObject (skier, maxCols/2, maxRows/2);
50 for (i = 0; i < MAX_OBJECTS; i++) {
51 objects[i] = makeObject (rand () % 3+1,
52 rand () % maxCols,
53 rand () % (maxRows*4 + maxRows/2));
54 }
55
56 objects[rand() % MAX_OBJECTS] = makeObject (bigfoot,
57 rand () % maxCols,
58 rand () % (maxRows*4 + maxRows/2));
59 objects[rand() % MAX_OBJECTS] = makeObject (snowman,
60 rand () % maxCols,
61 rand () % (maxRows*4 + maxRows/2));
62
63 /* Menu will go here */
64 printw ("GNUSki 0.3 - Skifree clone using NCurses, licensed under the GNU GPL.\n");
65 printw ("left, h, h - lean left\n");
66 printw ("right, L, l - lean right\n");
67 printw ("up, K, k - slow down\n");
68 printw ("down, J, j - speed up\n");
69 printw ("space - go into trick mode (beware, you can't move)\n");
70 printw ("Press any key to start...");
71 refresh ();
72 getch ();
73 nodelay (stdscr, true); /* No waiting for input from the user */
74 while (state == loop)
75 {
76 switch (c)
77 {
78 case KEY_LEFT: case 'h': case 'H':
79 if (player.trick) break;
80 facing[0] = '4';
81 facing[1] = '2';
82 break;
83 case KEY_RIGHT: case 'l': case 'L':
84 if (player.trick) break;
85 facing[0] = '3';
86 facing[1] = '1';
87 break;
88 case KEY_UP: case 'k': case 'K':
89 if (player.trick) break;
90 if (speed > 0)
91 speed--;
92 break;
93 case KEY_DOWN: case 'j': case 'J':
94 if (player.trick) break;
95 if (speed < 4)
96 speed++;
97 break;
98 case ' ':
99 player.trick++;
100 break;
101 case 'Q': case 'q':
102 state = lose;
103 break;
104 }
105
106 clear ();
107
108 /* Check for collisions and draw the objects */
109 for (i = 0; i < MAX_OBJECTS; i++)
110 {
111 if (objects[i].type != none && collision (player, objects[i]))
112 state = lose;
113 /* Calculate actual movement based on speed and frame counter */
114 int actual_speed = 0;
115 if (speed == 0) actual_speed = 0;
116 else if (speed == 1 && frame_counter % 4 == 0) actual_speed = 1;
117 else if (speed == 2 && frame_counter % 3 == 0) actual_speed = 1;
118 else if (speed == 3 && frame_counter % 2 == 0) actual_speed = 1;
119 else if (speed == 4) actual_speed = 1;
120
121 moveObject (&objects[i], facing[1], actual_speed);
122 if (objects[i].y < 0)
123 setPosition (&objects[i], rand () % (maxCols*2),
124 rand () % maxRows + maxRows);
125 if (objects[i].x > 2 && objects[i].x < maxCols-2
126 && objects[i].y > 2 && objects[i].y < maxRows-2)
127 draw (objects[i], facing[1]);
128 }
129 draw (player, facing[0]);
130 if (player.trick) {
131 style += 1;
132 player.trick -= 0.10;
133 if (player.trick < 0) player.trick = 0;
134 }
135 printw ("Time: 0:00:00.00\n");
136 printw ("Dist: %02im\n", distance);
137 printw ("Speed: %02im/s\n", speed);
138 printw ("Style: %4i (trick = %.2f%%)", style, player.trick*100);
139 distance += speed;
140 frame_counter++;
141 refresh ();
142 usleep(1000000 / fps);
143 c = getch ();
144 }
145 clear ();
146 if (state == win)
147 printw ("You won.");
148 else
149 printw ("You lost.");
150 printw ("Your score was %i. You traveled %im.\nPress any key to continue...",
151 distance+style, distance);
152 refresh ();
153 nodelay (stdscr, false);
154 getch ();
155
156 endwin ();
157 return 0;
158 }