this repo has no description
1#include "SDL_gpu.h"
2#include <stdlib.h>
3#include <math.h>
4
5#ifndef M_PI
6 #define M_PI 3.14159265358979323846
7#endif
8
9
10typedef struct Ship
11{
12 GPU_Image* image;
13
14 // Motion
15 float pos_x, pos_y;
16 float vel_x, vel_y;
17 float angle;
18
19 // Properties of the ship
20 float thrust;
21 float drag_coefficient;
22} Ship;
23
24Ship* create_ship(const char* image_file)
25{
26 Ship* ship = malloc(sizeof(Ship));
27 if(ship == NULL)
28 return NULL;
29
30 ship->image = GPU_LoadImage(image_file);
31 ship->pos_x = 0.0f;
32 ship->pos_y = 0.0f;
33 ship->vel_x = 0.0f;
34 ship->vel_y = 0.0f;
35 ship->angle = 0.0f;
36 ship->thrust = 500.0f;
37 ship->drag_coefficient = 0.00005f;
38
39 return ship;
40}
41
42void free_ship(Ship* ship)
43{
44 if(ship == NULL)
45 return;
46
47 GPU_FreeImage(ship->image);
48 free(ship);
49}
50
51void apply_thrust(Ship* ship, float dt)
52{
53 ship->vel_x += ship->thrust * cosf(ship->angle) * dt;
54 ship->vel_y += ship->thrust * sinf(ship->angle) * dt;
55}
56
57void apply_drag(Ship* ship, float dt)
58{
59 float vel_angle = atan2f(ship->vel_y, ship->vel_x);
60 float vel = sqrtf(ship->vel_x*ship->vel_x + ship->vel_y*ship->vel_y);
61 vel -= ship->drag_coefficient * vel * vel;
62 if(vel < 0)
63 vel = 0;
64
65 ship->vel_x = vel * cosf(vel_angle);
66 ship->vel_y = vel * sinf(vel_angle);
67}
68
69void update_ship(Ship* ship, GPU_Rect play_area, float dt)
70{
71 ship->pos_x += ship->vel_x * dt;
72 ship->pos_y += ship->vel_y * dt;
73
74 if(ship->pos_x < play_area.x)
75 {
76 ship->pos_x = play_area.x;
77 ship->vel_x = -ship->vel_x;
78 }
79 else if(ship->pos_x >= play_area.x + play_area.w)
80 {
81 ship->pos_x = play_area.x + play_area.w;
82 ship->vel_x = -ship->vel_x;
83 }
84
85 if(ship->pos_y < play_area.y)
86 {
87 ship->pos_y = play_area.y;
88 ship->vel_y = -ship->vel_y;
89 }
90 else if(ship->pos_y >= play_area.y + play_area.h)
91 {
92 ship->pos_y = play_area.y + play_area.h;
93 ship->vel_y = -ship->vel_y;
94 }
95}
96
97void draw_ship(Ship* ship, GPU_Target* screen)
98{
99 GPU_BlitRotate(ship->image, NULL, screen, ship->pos_x, ship->pos_y, ship->angle * 180 / M_PI);
100}
101
102
103
104int main(int argc, char* argv[])
105{
106 GPU_Target* screen;
107
108 GPU_SetDebugLevel(GPU_DEBUG_LEVEL_MAX);
109
110 screen = GPU_Init(800, 600, GPU_DEFAULT_INIT_FLAGS);
111 if(screen == NULL)
112 return -1;
113
114
115 {
116 // Loop variables
117 Uint32 start_time;
118 Uint32 end_time;
119 float dt;
120 Uint8 done;
121
122
123 // Interaction variables
124
125 Uint32 mouse_state;
126 int mouse_x, mouse_y;
127 SDL_Event event;
128
129 // Game variables
130
131 GPU_Rect play_area = {0, 0, screen->w, screen->h};
132
133 Ship* player_ship = create_ship("data/tutorial-space/ship.png");
134
135 if(player_ship == NULL || player_ship->image == NULL)
136 {
137 free_ship(player_ship);
138 return -2;
139 }
140
141
142 player_ship->pos_x = play_area.x + play_area.w/2;
143 player_ship->pos_y = play_area.y + play_area.h/2;
144
145
146 start_time = SDL_GetTicks();
147 dt = 0.0f;
148
149 done = 0;
150
151
152 // Game loop
153
154 while(!done)
155 {
156 // Check events
157
158 while(SDL_PollEvent(&event))
159 {
160 if(event.type == SDL_QUIT)
161 done = 1;
162 else if(event.type == SDL_KEYDOWN)
163 {
164 if(event.key.keysym.sym == SDLK_ESCAPE)
165 done = 1;
166 }
167 }
168
169 // Update
170
171 mouse_state = SDL_GetMouseState(&mouse_x, &mouse_y);
172
173 apply_drag(player_ship, dt);
174
175 player_ship->angle = atan2f(mouse_y - player_ship->pos_y, mouse_x - player_ship->pos_x);
176 if(mouse_state & SDL_BUTTON_LMASK)
177 apply_thrust(player_ship, dt);
178
179 update_ship(player_ship, play_area, dt);
180
181
182 // Draw
183
184 GPU_Clear(screen);
185
186 draw_ship(player_ship, screen);
187
188 GPU_Flip(screen);
189
190
191 // Timing
192
193 SDL_Delay(10);
194 end_time = SDL_GetTicks();
195 dt = (end_time - start_time)/1000.0f;
196 start_time = end_time;
197 }
198
199
200 // Clean up
201
202 free_ship(player_ship);
203 }
204
205 GPU_Quit();
206
207 return 0;
208}
209
210