浏览代码

HUGE REFACTOR. The code is now more modular and based on a system of States

Adrien Boucaud 12 年之前
父节点
当前提交
491a8b4a73
共有 12 个文件被更改,包括 315 次插入173 次删除
  1. 87 0
      draw_states.c
  2. 14 0
      draw_states.h
  3. 5 165
      hexagon.c
  4. 30 0
      init_states.c
  5. 10 0
      init_states.h
  6. 57 0
      states.c
  7. 13 0
      states.h
  8. 23 3
      struct.h
  9. 58 0
      update_states.c
  10. 14 0
      update_states.h
  11. 2 2
      wall.c
  12. 2 3
      wall.h

+ 87 - 0
draw_states.c

@@ -0,0 +1,87 @@
+#include "draw_states.h"
+void draw_game(Game_Data *data)
+{
+	//draw the player and the lines
+    drawPlayer(&(data->cam), data->player_angle);
+    drawDiagonal(1, data->cam);
+    drawDiagonal(2, data->cam);
+    drawDiagonal(3, data->cam);
+	//showing the walls
+    if(data->list != NULL)
+        drawWalls(data->list, &(data->cam));
+}
+void draw_title(Game_Data *data)
+{
+
+}
+void draw_menu(Game_Data *data)
+{
+
+}
+void draw_game_over(Game_Data *data)
+{
+
+}
+
+//draws the player
+//at first, was supposed to draw an hexagon in the center, plus a triangle to show the player,
+//but the hexagon was not visible, and it was a pixel mess, so we're showing a circle instead.
+//there is still for code to calculate the vertices of the hexagon, in case we want to change that again
+void drawPlayer(Camera *cam, int player_angle)
+{
+    int x[6];
+    int y[6];
+    int i = 0;
+    int angle = 0;
+    for(i = 0; i<6; ++i)
+    {
+        angle = i *60;
+
+        x[i] = 8.0*cos(PI * (angle + cam->angle)/180.0) + cam->cX;
+        y[i] = 8.0*sin(PI * (angle + cam->angle)/180.0) + cam->cY;
+    }
+
+	//draw the aforementionned circle, depending on the camera's center
+    //ML_filled_circle(cam.cX, cam.cY, 6, BLACK);
+	ML_polygone(x, y, 6, BLACK);
+	//draw the player. At such a low scale, it was impossible to draw a rotating triangle, so its a radius 1 circle instead.
+    ML_filled_circle(9*cos( PI*(player_angle + cam->angle)/180) + cam->cX, 9*sin( PI*(player_angle+cam->angle)/180) + cam->cY, 1, BLACK);
+
+}
+
+//draws one of the three rotating lines
+void drawDiagonal(int nb, Camera cam)
+{
+    int tmp_angle = 0;
+    float coeff = 0;
+    int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
+
+	//defining the angle between the line and the horizontal axis
+    if(nb == 1)
+        tmp_angle = cam.angle + 60;
+    else if(nb == 2)
+        tmp_angle = cam.angle;
+    else if(nb == 3)
+        tmp_angle = 300 + cam.angle;
+    if(tmp_angle >= 360)tmp_angle = tmp_angle - 359;
+
+	//defining the slope coefficient
+    coeff = sin(PI*tmp_angle / 180)/cos(PI * tmp_angle / 180);
+
+	//ML needs four coordinates in order to draw a line
+    x1 = -32/coeff;
+    y1 = -32;
+
+    x2 = 32/coeff;
+    y2 = 32;
+
+    if(abs(x1) > 64){
+        x1 = -64;
+        y1 = -64*coeff;
+
+        x2 = 64;
+        y2 = 64*coeff;
+    }
+	//drawing the line
+        ML_line(x1 + cam.cX, y1 + cam.cY, x2 + cam.cX, y2 + cam.cY, BLACK);
+}

+ 14 - 0
draw_states.h

@@ -0,0 +1,14 @@
+#ifndef DRAW_STATES_H
+#define DRAW_STATES_H
+#include "math.h"
+#include "struct.h"
+#include "MonochromeLib.h"
+
+void draw_game(Game_Data *data);
+void draw_title(Game_Data *data);
+void draw_menu(Game_Data *data);
+void draw_game_over(Game_Data *data);
+
+void drawPlayer(Camera *cam, int player_angle);
+void drawDiagonal(int nb, Camera cam);
+#endif

+ 5 - 165
hexagon.c

@@ -2,39 +2,15 @@
 #include "MonochromeLib.h"
 #include "math.h"
 #include "ECode.h"
-#include "stdlib.h"
 #include "struct.h"
 #include "wall.h"
 #include "syscall.h"
+#include "states.h"
 
-#define FPS 60
-//duration of a frame
-#define FRAME_TIME 1/FPS
-
-//oriented angle between the player and the horizontal axis
-int player_angle=0;
-
-Camera cam = {64, 32, 0, 0};
-
-//linked list of obstacles
-//at the moment, there is only a list, but at term, we should be using the lists from the Line struct. (And thus remove the "line" member from the Wall struct
-Wall *list = NULL;
-
-//delta angle: defines the 'speed' of the camera
-
-//function prototypes
-//draws the player
-void drawPlayer();
-//draws one of the lines (from 0 to 2)
-void drawDiagonal(int nb);
-
-void updateCamera(Camera *cam, unsigned int delta_time);
 
 int AddIn_main(int isAppli, unsigned short OptionNum)
 {
-    unsigned int start_time = RTC_GetTicks(); //1 tick == 1/128 second
-    unsigned int last_time = 0;
-    unsigned int current_time = RTC_GetTicks();
+    Game_Data data;
 	//variables for fps calculation
     unsigned int fps = 0, frame = 0, tempsOrigine = RTC_GetTicks();
 	//char string to display the fps
@@ -42,11 +18,9 @@ int AddIn_main(int isAppli, unsigned short OptionNum)
 	//rand initialisation
     srand(RTC_GetTicks());
 
-    //list = addWall(list, 128, 8, 1, 1);
+    switch_to_state(GAME, &data);
 
     while(KeyUp(K_EXIT)){ //main loop
-    	last_time = current_time;
-	current_time = RTC_GetTicks();
         //fps
         if(RTC_GetTicks() - tempsOrigine >= 32 )//if 1/4 seconds elapsed
         {
@@ -55,158 +29,24 @@ int AddIn_main(int isAppli, unsigned short OptionNum)
             tempsOrigine = RTC_GetTicks();
         }
         frame++;
-        if(list != NULL){ //if the linked list is not empty
-            update(list, current_time - last_time); //update the linked list
 
-        if(isColliding(list, player_angle) == true) //if the player and a wall collide
-     	{
-            PrintMini(50, 0, "TOUCHE", MINI_OVER); //death handling
-        }
-            list = removeWall(list, 0); //remove every wall whose distance to the center equals zero
-
-        }
-	//level generation
-	//TODO: something else than pure randomness
-        if(rand() % 40 == 1)//
-        {
-            list = addWall(list, 128, 8, 1, rand()%6);
-        }else if(rand() % 70 == 1)
-        {
-            int emptyRow = rand()%6;
-            int i = 0;
-            for(i = 0; i < 6; i++)
-                if(i != emptyRow)
-                    list = addWall(list, 128, 15, 1, i);
-        }
-	//draw the player and the lines
-        drawPlayer();
-        drawDiagonal(1);
-        drawDiagonal(2);
-        drawDiagonal(3);
+        update(&data);
+        draw(&data);
 
 	//printing debug information
         intToStr(fps_text, fps);
         PrintMini(0, 0, fps_text, MINI_OVER);
-        intToStr(fps_text, player_angle);
-        PrintMini(116, 0, fps_text, MINI_OVER);
-
-	//showing the walls
-        if(list != NULL)
-            show(list, &cam);
 
 	//updating the screen
         ML_display_vram();
         ML_clear_vram();
 
-	//player input
-	//TODO: no magic values
-        if(KeyDown(K_LEFT))
-        {
-            player_angle-=15;
-        }
-        if(KeyDown(K_RIGHT))
-        {
-            player_angle+=15;
-        }
-
-	updateCamera(&cam, current_time - last_time);
-	//manually change the rotation speed
-	//TODO: automatize this
-/*        if(KeyDown(K_PLUS))
-        {
-            dAngle += 0.2;
-        }
-        if(KeyDown(K_MINUS))
-        {
-            dAngle -= 0.2;
-        }
-*/
-	//the angle must not be greater than 360
-        if(player_angle < 0)
-            player_angle = 360 + player_angle;
-        player_angle = player_angle % 360;
-
-        if(player_angle > 360)
-        {
-            while(KeyUp(K_EXE))
-            {}
-        }
-        //while
-	//pause
         Sleep(1/0.06);
     }
 
     return 1;
 }
 
-void updateCamera(Camera *cam, unsigned int delta_time){
-	cam->speed = 1; //to change
-	cam->angle += cam->speed * delta_time / 2.;
-
-	if(cam->angle >= 360)
-		cam->angle -= 359;
-}
-//draws the player
-//at first, was supposed to draw an hexagon in the center, plus a triangle to show the player,
-//but the hexagon was not visible, and it was a pixel mess, so we're showing a circle instead.
-//there is still for code to calculate the vertices of the hexagon, in case we want to change that again
-void drawPlayer()
-{
-    int x[6];
-    int y[6];
-    int i = 0;
-
-    for(i = 0; i<6; ++i)
-    {
-        int angle = i *60;
-        x[i] = 8.*cos(PI * (angle + cam.angle)/180.) + cam.cX;
-        y[i] = 8.*sin(PI * (angle + cam.angle)/180.) + cam.cY;
-    }
-
-	//draw the aforementionned circle, depending on the camera's center
-    //ML_filled_circle(cam.cX, cam.cY, 6, BLACK);
-	ML_polygone(x, y, 6, BLACK);
-	//draw the player. At such a low scale, it was impossible to draw a rotating triangle, so its a radius 1 circle instead.
-    ML_filled_circle(9*cos( PI*(player_angle + cam.angle)/180) + cam.cX, 9*sin( PI*(player_angle+cam.angle)/180) + cam.cY, 1, BLACK);
-
-}
-
-//draws one of the three rotating lines
-void drawDiagonal(int nb)
-{
-    int tmp_angle = 0;
-    float coeff = 0;
-    int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
-
-	//defining the angle between the line and the horizontal axis
-    if(nb == 1)
-        tmp_angle = cam.angle + 60;
-    else if(nb == 2)
-        tmp_angle = cam.angle;
-    else if(nb == 3)
-        tmp_angle = 300 + cam.angle;
-    if(tmp_angle >= 360)tmp_angle = tmp_angle - 359;
-
-	//defining the slope coefficient
-    coeff = sin(PI*tmp_angle / 180)/cos(PI * tmp_angle / 180);
-
-	//ML needs four coordinates in order to draw a line
-    x1 = -32/coeff;
-    y1 = -32;
-
-    x2 = 32/coeff;
-    y2 = 32;
-
-    if(abs(x1) > 64){
-        x1 = -64;
-        y1 = -64*coeff;
-
-        x2 = 64;
-        y2 = 64*coeff;
-    }
-	//drawing the line
-        ML_line(x1 + cam.cX, y1 + cam.cY, x2 + cam.cX, y2 + cam.cY, BLACK);
-}
 
 #pragma section _BR_Size
 unsigned long BR_Size;

+ 30 - 0
init_states.c

@@ -0,0 +1,30 @@
+#include "init_states.h"
+
+void init_game(Game_Data *data)
+{
+	data->level = NULL;
+	data->list = NULL;
+	data->start_time = RTC_GetTicks(); //1 tick == 1/128 second
+	data->last_time = 0;
+	data->current_time = RTC_GetTicks();
+
+	data->player_angle = 0;
+
+	data->cam.cX = 64;
+	data->cam.cY = 32;
+	data->cam.angle = 0;
+	data->cam.speed = 0.0;
+}
+void init_title(Game_Data *data)
+{
+
+
+}
+void init_menu(Game_Data *data)
+{
+
+}
+void init_game_over(Game_Data *data)
+{
+
+}

+ 10 - 0
init_states.h

@@ -0,0 +1,10 @@
+#ifndef INIT_STATES_H
+#define INIT_STATES_H
+#include "struct.h"
+
+void init_game(Game_Data *data);
+void init_title(Game_Data *data);
+void init_menu(Game_Data *data);
+void init_game_over(Game_Data *data);
+
+#endif

+ 57 - 0
states.c

@@ -0,0 +1,57 @@
+#include "states.h"
+
+State current_state = GAME;
+void switch_to_state(State new_state, Game_Data *data)
+{
+	switch (new_state)
+	{
+		case GAME:
+			init_game(data);
+		break;
+		case TITLE:
+			init_title(data);
+		break;
+		case MENU:
+			init_menu(data);
+		break;
+		case GAME_OVER:
+			init_game_over(data);
+		break;
+	}
+}
+void update(Game_Data *data)
+{
+	switch(current_state)
+	{
+		case GAME:
+			update_game(data);
+		break;
+		case TITLE:
+			update_title(data);
+		break;
+		case MENU:
+			update_menu(data);
+		break;
+		case GAME_OVER:
+			update_game_over(data);
+		break;
+	}
+}
+void draw(Game_Data *data)
+{
+	switch(current_state)
+	{
+		case GAME:
+			draw_game(data);
+		break;
+		case TITLE:
+			draw_title(data);
+		break;
+		case MENU:
+			draw_menu(data);
+		break;
+		case GAME_OVER:
+			draw_game_over(data);
+		break;
+	}
+}

+ 13 - 0
states.h

@@ -0,0 +1,13 @@
+#ifndef STATES_H
+#define STATES_H
+
+#include "update_states.h"
+#include "init_states.h"
+#include "draw_states.h"
+#include "struct.h"
+
+void switch_to_state(State new_state, Game_Data *data);
+void update(Game_Data *data);
+void draw(Game_Data *data);
+
+#endif

+ 23 - 3
struct.h

@@ -1,7 +1,11 @@
 #ifndef STRUCT_H
 #define STRUCT_H
 
+#include "stdlib.h"
+
 //constants
+#define FPS 60
+#define FRAME_TIME 1/FPS
 #define PI 3.14159265
 #define SIN_60 0.866025404
 #define COS_60 0.5
@@ -11,20 +15,22 @@
 
 //macros
 #define abs(x) x>0 ? x : -x
-typedef enum Pattern_Enum Pattern_Enum;
+typedef enum {PATTERN} Pattern_Enum;
 typedef struct Camera Camera;
 typedef struct Wall Wall;
 typedef struct Line Line;
 typedef struct Level Level;
+typedef struct Game_Data Game_Data;
+typedef enum {GAME, MENU, TITLE, GAME_OVER} State;
 
 struct Level{
 	//for the level generation
-	Pattern_Enum available_patterns[][];
+	Pattern_Enum available_patterns[32][32];
 	int nb_patterns;
 
 	//for the camera rotation
 	int change_interval; //5 seconds most of the time, but who knows...
-	int change_precision //to add a bit of randomness to the intervals
+	int change_precision; //to add a bit of randomness to the intervals
 	float change_probability; //sometimes, there can be no change at all
 	
 	float max_speed;
@@ -58,4 +64,18 @@ struct Wall{
 
     Wall *nxt;
 };
+
+struct Game_Data{
+	unsigned int start_time;
+	unsigned int last_time;
+	unsigned int current_time;
+	unsigned int player_angle;
+
+	Wall *list;
+
+	Level *level;
+
+	Camera cam;
+};
+
 #endif

+ 58 - 0
update_states.c

@@ -0,0 +1,58 @@
+#include "update_states.h"
+
+void update_title(Game_Data *data)
+{
+//TODO
+}
+void update_game(Game_Data *data)
+{
+    data->last_time = data->current_time;
+    data->current_time = RTC_GetTicks();
+    if(data->list != NULL){ //if the linked list is not empty
+            updateWalls(data->list, data->current_time - data->last_time); //update the linked list
+
+        if(isColliding(data->list, data->player_angle) == true){ //if the player and a wall collide
+            PrintMini(50, 0, "TOUCHE", MINI_OVER); //death handling
+    	}
+        data->list = removeWall(data->list, 0); //remove every wall whose distance to the center equals zero
+    }
+	//level generation
+	//TODO: something else than pure randomness
+    if(rand() % 40 == 1){
+        data->list = addWall(data->list, 128, 8, 1, rand()%6);
+    }else if(rand() % 70 == 1){
+        int emptyRow = rand()%6;
+        int i = 0;
+        for(i = 0; i < 6; i++)
+            if(i != emptyRow)
+                data->list = addWall(data->list, 128, 15, 1, i);
+    }
+    if(KeyDown(K_LEFT)){
+        data->player_angle-=15;
+    }
+    if(KeyDown(K_RIGHT)){
+        data->player_angle+=15;
+    }
+
+    //the angle must not be greater than 360
+    if(data->player_angle < 0)
+        data->player_angle = 360 + data->player_angle;
+    data->player_angle = data->player_angle % 360;
+	updateCamera(&(data->cam), data->current_time - data->last_time);
+}
+void update_menu(Game_Data *data)
+{
+//TODO
+}
+void update_game_over(Game_Data *data)
+{
+//TODO
+}
+
+void updateCamera(Camera *cam, unsigned int delta_time){
+    cam->speed = 1; //to change
+    cam->angle += cam->speed * delta_time / 2.;
+
+    if(cam->angle >= 360)
+        cam->angle -= 359;
+}

+ 14 - 0
update_states.h

@@ -0,0 +1,14 @@
+#ifndef UPDATE_STATES_H
+#define UPDATE_STATES_H
+#include "fxlib.h"
+#include "ECode.h"
+#include "struct.h"
+#include "wall.h"
+
+void update_game(Game_Data *data);
+void update_title(Game_Data *data);
+void update_menu(Game_Data *data);
+void update_game_over(Game_Data *data);
+void updateCamera(Camera *cam, unsigned int delta_time);
+
+#endif

+ 2 - 2
wall.c

@@ -59,7 +59,7 @@ Wall *removeWall(Wall *list, int d)
 	return list;
 }
 
-void update(Wall *list, unsigned int delta_time)
+void updateWalls(Wall *list, unsigned int delta_time)
 {
 	//we want to move the obstacle by 1 every two ticks (1/64 seconds ~= 1/60)
 	//
@@ -87,7 +87,7 @@ int getSlopeIndex(int dot1, int dot2)
 		return dot2;
 	}else return 3;
 }
-void show(Wall *list, Camera *cam)
+void drawWalls(Wall *list, Camera *cam)
 {
 	Wall *tmp;
 	tmp = list;

+ 2 - 3
wall.h

@@ -1,7 +1,6 @@
 #ifndef WALL_H
 #define WALL_H
 
-#include "stdlib.h"
 #include "struct.h"
 #include "MonochromeLib.h"
 #include "math.h"
@@ -11,9 +10,9 @@ Wall *addWall(Wall *list, int d, int h, int id, int line);//returns a new pointe
 Wall *removeWall(Wall *list, int d); //returns a new pointer to the first element
 
 //show the ll "list"
-void show(Wall *list, Camera *cam);
+void drawWalls(Wall *list, Camera *cam);
 //updates the ll "list"
-void update(Wall *list, unsigned int delta_time);
+void updateWalls(Wall *list, unsigned int delta_time);
 //simple collision test. Returns true if a Wall from the list collides with the player
 bool isColliding(Wall *list, int player_angle);
 #endif