70 Commits

Author SHA1 Message Date
44531ab24e Fix formatting of README.md 2026-03-03 09:28:44 +01:00
c1139ddb81 Change README to markdown. 2026-03-03 09:26:50 +01:00
da8d83de92 Remove fullscreen to-do item. 2026-03-03 09:23:36 +01:00
bc6881f851 Revert "Move global variables to main()."
This reverts commit b842bd0095.
2026-03-03 09:22:16 +01:00
b842bd0095 Move global variables to main().
Should not make variables global unnecessarily.
2026-03-03 09:20:50 +01:00
bb28285794 Fix possible precision loss by converting to float. 2026-03-03 09:20:00 +01:00
6621decc09 Add fullscreen mode support. 2026-03-03 09:19:16 +01:00
fd9fd453b3 Add help information for pause button. 2026-03-03 08:26:53 +01:00
b0f4f6849d Update CMake minimum required version to 3.10
This is needed to build with modern versions of CMake.
2026-03-03 08:21:01 +01:00
8924741937 Remove from the TODO 2018-04-13 08:02:55 +02:00
63f950e26b Implement pause functionality. 2018-04-13 08:02:34 +02:00
349848ebf6 Remove extra 5.0 stuff (fix later). 2018-04-13 08:01:53 +02:00
395c3c854f Require minimum version of Allegro. 2018-04-04 11:55:02 +02:00
a93e9a7b73 For compatibility with Debian systems.
For some reason they specify the minor version too, which is retarded.
2018-04-04 11:51:20 +02:00
29219bbc2c Added a TODO list. 2018-03-29 13:04:35 +02:00
d343c5e5a0 Move help information further up. 2018-03-29 13:01:09 +02:00
17777e2178 No need to update the ship if we reset. 2018-03-29 12:58:37 +02:00
609d197227 Better description. 2018-03-29 12:56:01 +02:00
e29a0bc7a3 Slower acceleration. 2018-03-29 12:55:48 +02:00
92e406bc74 Measure by pixel/second 2018-03-29 11:57:17 +02:00
2d64adf476 Put version in window title. 2018-03-29 01:06:15 +02:00
ab10fcdf02 Reset simulation feature added. 2018-03-25 18:45:28 +02:00
c51f34c888 Fully functional simulation.
I still need to add the restart feature.
2018-03-25 18:43:06 +02:00
85435fef8d Added help information. 2018-03-25 18:24:39 +02:00
8e10be3ea9 Forgot to update x and y variables. 2018-03-25 18:02:09 +02:00
b41719855a Set ship turning correctly. 2018-03-25 17:57:37 +02:00
008ec2bd72 Added keyboard event source. 2018-03-25 17:57:21 +02:00
88f3a5f1a5 Added malfunctioning ship.
Currently it doesn't seem to be detecting the key preses.
2018-03-25 17:47:31 +02:00
80113d51ff Remove global variables.
Global variables are overall bad practice.
2018-03-25 17:14:44 +02:00
0faa83c162 Remove help and info from key list. 2018-03-25 17:04:14 +02:00
4dc7fbbf04 Create a ship object. 2018-03-25 16:59:03 +02:00
a1406c4506 Included debug information. 2018-03-25 16:44:09 +02:00
86159b0b69 Initialize the primitives addon. 2018-03-25 16:42:00 +02:00
fb023194e3 Add fast-math optimization for release builds. 2018-03-25 16:40:56 +02:00
5cefcd8554 Added section of v0.3. 2018-03-25 15:46:46 +02:00
fa9a35444b Invalid keycodes also return 0 (but print a msg in DEBUG). 2018-03-25 15:34:53 +02:00
d871bcec41 Implemented key_is_down() function. 2018-03-25 15:29:48 +02:00
ea4f4a97b6 Keyboard input added. 2018-03-25 15:22:43 +02:00
d57da20ec7 Created an event manager. 2018-03-25 14:53:40 +02:00
b99e33fe52 A changelog file of previous releases. 2018-03-25 14:53:08 +02:00
768f80a362 Create a display. 2018-03-25 14:27:10 +02:00
8c19b96bb7 New install target. 2018-03-25 12:30:39 +02:00
1cdd5964f0 First steps. 2018-03-25 12:08:19 +02:00
a54d54d993 Use floats for less precision (we don't need doubles). 2016-09-18 16:17:34 +02:00
Nicolás A. Ortega
8551012cac Update README.md 2014-10-30 15:46:23 -05:00
Deathsbreed
83e84ba74c Moved Windows class inside the SpaceShipSim class (for file simplicity). 2014-10-10 11:48:32 -05:00
Deathsbreed
7ed497892b Update README.md 2014-10-08 19:45:05 -05:00
Deathsbreed
091b9f704e Simplified compiling. 2014-10-08 19:44:41 -05:00
Deathsbreed
07a36e01e4 Added some getter/setter methods. 2014-10-01 12:10:05 -05:00
Deathsbreed
a8303ba13c Removed '+' from the 'About' page. 2014-09-22 08:31:29 -05:00
Deathsbreed
5b577f3405 Update README.md 2014-09-20 18:56:25 -05:00
Deathsbreed
efae00fd45 Changed README for compile information. 2014-09-20 18:53:20 -05:00
Deathsbreed
d072de67dd Changing to using ant for compiling. 2014-09-20 18:52:10 -05:00
Nicolás A. Ortega
bc6085609f Update README.md 2014-09-17 21:19:29 -05:00
Deathsbreed
b78d4eef85 Removed some commented lines. 2014-05-31 17:42:09 -05:00
Deathsbreed
a05307f38a Set version variable to prepare for the next version (I tend to forget that kind of stuff). 2014-05-28 10:15:20 -05:00
Deathsbreed
84dd04008f Added shortcut to reset. 2014-05-28 09:56:12 -05:00
Deathsbreed
574c562299 There is now a Window that opens to display information, and various new menu
items. There is also a shortcut to quit the application.
2014-05-28 09:38:05 -05:00
Deathsbreed
9f232d9e46 Added more menu items to the help menu that still don't work. It'll need some work. 2014-05-27 20:53:29 -05:00
Deathsbreed
390a1460f2 Added STUFF comments since I do not like blank spaces. 2014-05-27 20:45:42 -05:00
Deathsbreed
b0360f7308 Added new not-finished class for About window. 2014-05-27 20:43:58 -05:00
Deathsbreed
f6cfb9c0bc Added a Reset button, and a not working About button. 2014-05-27 20:43:11 -05:00
Deathsbreed
d7911b01c5 KeyListener fixed! 2014-05-27 19:21:17 -05:00
Deathsbreed
a511027e16 Got the menus working, now the KeyListener needs to be fixed. 2014-05-27 17:05:04 -05:00
Deathsbreed
2cc5153497 Added FIXME to corresponding section. 2014-05-27 08:21:20 -05:00
Deathsbreed
e19278dfec Trying to create menu bar. 2014-05-27 08:15:09 -05:00
Deathsbreed
3174669ec3 Forget about the gitignore, it is fine. 2014-05-26 16:39:33 -05:00
Deathsbreed
6ddb1fd610 Seeing if I can stop .gitignore from appearing on the website 2014-05-26 16:38:41 -05:00
Deathsbreed
60e396102d Merge branch 'master' of https://github.com/Deathsbreed/SpaceShipSim 2014-05-26 16:36:21 -05:00
Deathsbreed
0c921ea7fd Trying to see if gitignore works 2014-05-26 16:35:29 -05:00
15 changed files with 718 additions and 254 deletions

3
.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
# Ignore build files
build/*
!build/.keep

10
CHANGELOG Normal file
View File

@@ -0,0 +1,10 @@
v0.1: First Release
- Basic simulation.
- Information printing.
v0.2: Menu Bar
- Added a menu bar.
- Can reset the simulation.
v0.3: Port to C
- Codebase ported to C for better performance.

68
CMakeLists.txt Normal file
View File

@@ -0,0 +1,68 @@
# Copyright (C) 2026 Ortega Froysa, Nicolás <nicolas@ortegas.org>
# Author: Ortega Froysa, Nicolás <nicolas@ortegas.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
cmake_minimum_required(VERSION 3.10)
project(SpaceShipSim C)
set(TARGET_NAME "spaceshipsim")
set(TARGET_VERSION "0.3")
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "release")
endif()
string(TOLOWER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE)
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
set(CMAKE_C_FLAGS "-std=c99 -Wall -Wextra -Werror")
set(CMAKE_C_FLAGS_DEBUG "-g -O0")
set(CMAKE_C_FLAGS_RELEASE "-O3 -ffast-math")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "-g -O3 -ffast-math")
set(CMAKE_C_FLAGS_MINSIZEREL "-Os")
find_package(PkgConfig REQUIRED)
pkg_check_modules(ALLEG5 REQUIRED allegro-5>=5.1.9)
pkg_check_modules(ALLEG5-PRIM REQUIRED allegro_primitives-5)
pkg_check_modules(ALLEG5-FONT REQUIRED allegro_font-5)
include_directories(
SYSTEM ${ALLEG5_INCLUDE_DIRS})
set(SRCS
src/event_manager.c
src/main.c
src/ship.c)
add_definitions(-DVERSION="${TARGET_VERSION}")
if(${CMAKE_BUILD_TYPE} STREQUAL "debug" OR
${CMAKE_BUILD_TYPE} STREQUAL "relwithdebinfo")
add_definitions(-DDEBUG)
else()
add_definitions(-DNDEBUG)
endif()
add_executable(${TARGET_NAME} ${SRCS})
target_link_libraries(${TARGET_NAME}
m # math library
${ALLEG5_LIBRARIES}
${ALLEG5-PRIM_LIBRARIES}
${ALLEG5-FONT_LIBRARIES})
install(TARGETS ${TARGET_NAME}
RUNTIME DESTINATION bin/
CONFIGURATIONS release minsizerel)

View File

@@ -1,10 +1,40 @@
SpaceShipSim
============
# SpaceShipSim
Space Ship Simulator is a basic 2D simulator of a spaceship in a frictionless environment. This program was made for educational purposes, and is meant to be quite simple.
This is a small simulation program of a space ship (with infinite fuel) in a
frictionless environment (space). The idea is to use it for educational
purposes.
To compile the source-code, go into the project src/ folder and run the following command:<br>
<code>$ javac spaceshipsim/SpaceShipSim.java</code>
## Compiling
<h4>Contributing</h4>
If you wish to contribute, feel free! Make sure to contact me at nicolas.ortega.froysa@gmail.com to give you permission to modify the project on Github. Or, you can make your own branch or fork this project!
In order to build this program you will require the following dependencies:
- A C compiler that supports C99 or higher
- CMake 3.10 or higher
- Allegro 5
You can then compile the program via the following commands:
```bash
cd build/
cmake ..
make
```
This will create a release build with compiler optimizations. If you would like
a debug build then pass the `-DCMAKE_BUILD_TYPE=debug` flag to the `cmake`
command. If you would like to install then run `cmake` with the additional flag
`-DCMAKE_INSTALL_PREFIX=<install_dir>`. If you are installing as a user then
you may want to set the installation prefix to `/usr/local/`, and if you're
packaging then please consult your distribution's policies. With this you
should be able to run the `make install' target and install the binary.
## Contributing
If you would like to contribute to the project, send a patch file to my e-mail
address: <nortega@themusicinnoise.net>.
## License
As educational software, unless otherwise noted, all files are licensed under
the terms & conditions of the GNU General Public License version 3 or greater
(see `LICENSE' file for more information).

2
TODO Normal file
View File

@@ -0,0 +1,2 @@
TODO:
- Add presets with stellar masses (for gravity simulation).

0
build/.keep Normal file
View File

147
src/event_manager.c Normal file
View File

@@ -0,0 +1,147 @@
/*
* Copyright (C) 2018 Ortega Froysa, Nicolás <nortega@themusicinnoise.net>
* Author: Ortega Froysa, Nicolás <nortega@themusicinnoise.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "event_manager.h"
#include "globals.h"
#ifdef DEBUG
# include <stdio.h>
#endif
#include <stddef.h>
#include <assert.h>
#include <allegro5/allegro.h>
static ALLEGRO_EVENT_QUEUE *event_queue;
static ALLEGRO_TIMER *timer;
static int keys[KEY_MAX];
int evnt_mngr_init(ALLEGRO_DISPLAY *display) {
assert(display);
if(!al_install_keyboard())
return 0;
#ifdef DEBUG
puts("Initialized keyboard.");
#endif
timer = al_create_timer(1.0f / FPS);
if(!timer)
return 0;
#ifdef DEBUG
puts("Initialized timer.");
#endif
event_queue = al_create_event_queue();
if(!event_queue)
{
al_destroy_timer(timer);
return 0;
}
#ifdef DEBUG
puts("Initialized event queue.");
#endif
al_register_event_source(event_queue,
al_get_display_event_source(display));
al_register_event_source(event_queue,
al_get_timer_event_source(timer));
al_register_event_source(event_queue,
al_get_keyboard_event_source());
al_start_timer(timer);
// set all keys to false at initialization
for(size_t i = 0; i < KEY_MAX; ++i)
keys[i] = 0;
return 1;
}
void evnt_mngr_deinit() {
al_destroy_timer(timer);
#ifdef DEBUG
puts("Destroyed timer.");
#endif
al_destroy_event_queue(event_queue);
#ifdef DEBUG
puts("Destroyed event queue.");
#endif
}
void set_key(int keycode, int value) {
switch(keycode)
{
case ALLEGRO_KEY_UP:
keys[KEY_UP] = value;
break;
case ALLEGRO_KEY_DOWN:
keys[KEY_DOWN] = value;
break;
case ALLEGRO_KEY_LEFT:
keys[KEY_LEFT] = value;
break;
case ALLEGRO_KEY_RIGHT:
keys[KEY_RIGHT] = value;
break;
case ALLEGRO_KEY_R:
keys[KEY_RESET] = value;
break;
case ALLEGRO_KEY_F:
keys[KEY_FULLSCREEN] = value;
break;
case ALLEGRO_KEY_P:
keys[KEY_PAUSE] = value;
break;
default:
break;
}
}
void handle_event() {
ALLEGRO_EVENT evnt;
al_wait_for_event(event_queue, &evnt);
do
{
switch(evnt.type)
{
case ALLEGRO_EVENT_TIMER:
redraw = 1;
break;
case ALLEGRO_EVENT_DISPLAY_CLOSE:
run = 0;
break;
case ALLEGRO_EVENT_KEY_DOWN:
if(evnt.keyboard.keycode == ALLEGRO_KEY_H)
show_help = !show_help;
else if(evnt.keyboard.keycode == ALLEGRO_KEY_I)
show_info = !show_info;
else if(evnt.keyboard.keycode == ALLEGRO_KEY_Q ||
evnt.keyboard.keycode == ALLEGRO_KEY_ESCAPE)
run = 0;
else
set_key(evnt.keyboard.keycode, 1);
break;
case ALLEGRO_EVENT_KEY_UP:
set_key(evnt.keyboard.keycode, 0);
break;
}
} while(al_get_next_event(event_queue, &evnt));
}
int key_is_down(int code) {
assert(code >= 0 && code <= KEY_MAX);
return keys[code];
}

62
src/event_manager.h Normal file
View File

@@ -0,0 +1,62 @@
/*
* Copyright (C) 2018 Ortega Froysa, Nicolás <nortega@themusicinnoise.net>
* Author: Ortega Froysa, Nicolás <nortega@themusicinnoise.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <allegro5/allegro.h>
enum {
KEY_UP = 0x0,
KEY_DOWN = 0x1,
KEY_LEFT = 0x2,
KEY_RIGHT = 0x3,
KEY_RESET = 0x4,
KEY_FULLSCREEN = 0x5,
KEY_PAUSE = 0x6,
KEY_MAX = 0x7
};
/**
* @brief Initialize the event handler.
*
* @param display A pointer to the display (used to get
* event source).
*
* @return 0 upon failure, 1 upon success.
*/
int evnt_mngr_init(ALLEGRO_DISPLAY *display);
/**
* @brief Deinitialize the event handler.
*/
void evnt_mngr_deinit();
/**
* @brief Handle the next event in the queue (wait if the
* queue is empty).
*/
void handle_event();
/**
* @brief Receive state of a key.
*
* @param code The key code.
*
* @return If down 1 will be returned, else 0.
*/
int key_is_down(int code);

54
src/globals.h Normal file
View File

@@ -0,0 +1,54 @@
/*
* Copyright (C) 2018 Ortega Froysa, Nicolás <nortega@themusicinnoise.net>
* Author: Ortega Froysa, Nicolás <nortega@themusicinnoise.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifndef VERSION
# define VERSION "[version]"
#endif
#ifndef FPS
# define FPS 60.0f
#endif
#ifndef ACCEL
# define ACCEL 0.1f
#endif
#ifndef TURN_ACCEL
# define TURN_ACCEL (M_PI / FPS) // turn at pi radians / sec
#endif
#ifndef WINDOW_WIDTH
# define WINDOW_WIDTH 800
#endif
#ifndef WINDOW_HEIGHT
# define WINDOW_HEIGHT 600
#endif
#include <math.h>
#ifndef M_PI
# define M_PI 3.14159265f
#endif
#define RAD_TO_DEG(x) (x * 180 / M_PI)
#include <allegro5/allegro.h>
extern int redraw; ///< Whether or not to redraw the screen.
extern int run; ///< Whether or not to continue running the simulation.
extern int show_help; ///< Whether or not to show the help info.
extern int show_info; ///< Whether or not to show simulation info.

196
src/main.c Normal file
View File

@@ -0,0 +1,196 @@
/*
* Copyright (C) 2018 Ortega Froysa, Nicolás <nortega@themusicinnoise.net>
* Author: Ortega Froysa, Nicolás <nortega@themusicinnoise.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "globals.h"
#include "event_manager.h"
#include "ship.h"
int run;
int redraw;
int show_help;
int show_info;
#include <stdio.h>
#include <allegro5/allegro.h>
#include <allegro5/allegro_primitives.h>
#include <allegro5/allegro_font.h>
const char *help =
"HELP:\n"
"LEFT/RIGHT - turn the ship\n"
"UP/DOWN - accelerate/reverse accelerate\n"
"R - reset the simulation\n"
"P - pause/unpause the simulation\n"
"I - show/hide simulation information\n"
"H - show/hide this help information\n"
"F - toggle fullscreen\n"
"Q/ESC - quit";
const char *info_format =
"INFO:\n"
"x: %f\n"
"y: %f\n"
"angle: %f (%f degrees)\n"
"velX: %f px/sec\n"
"velY: %f px/sec";
int main() {
char title[32];
sprintf(title, "SpaceShipSim v%s", VERSION);
puts(title);
if(!al_init())
{
fprintf(stderr, "alleg5: failed to initialize Allegro.\n");
return 1;
}
#ifdef DEBUG
puts("Initialized allegro system.");
#endif
if(!al_init_primitives_addon())
{
fprintf(stderr, "alleg5: failed to initialize primitives addon.\n");
return 1;
}
#ifdef DEBUG
puts("Initialized primitives addon.");
#endif
if(!al_init_font_addon())
{
fprintf(stderr, "alleg5: failed to initialize font addon.\n");
return 1;
}
ALLEGRO_DISPLAY *display = al_create_display(WINDOW_WIDTH, WINDOW_HEIGHT);
if(!display)
{
fprintf(stderr, "alleg5: failed to initialize display.\n");
return 1;
}
al_set_window_title(display, title);
#ifdef DEBUG
puts("Created display.");
#endif
if(!evnt_mngr_init(display))
{
fprintf(stderr, "alleg5: failed to initialize event queue.\n");
al_destroy_display(display);
return 1;
}
// initialize the spaceship at the center of the screen
struct ship ship;
ship_init(&ship, 400, 300);
ALLEGRO_FONT *font = al_create_builtin_font();
// begin running the simulation
run = 1;
redraw = 1;
show_help = 1;
show_info = 1;
int paused = 0;
int old_paused = 0;
int just_toggled_fullscreen = 0;
while(run)
{
handle_event();
// only redraw or run simulation if the timer event has occurred
if(redraw)
{
if(paused == old_paused && key_is_down(KEY_PAUSE))
paused = !paused;
else if(paused != old_paused && !key_is_down(KEY_PAUSE))
old_paused = paused;
if(!paused)
{
if(key_is_down(KEY_RESET))
ship_init(&ship, WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2);
else
ship_update(&ship);
}
if (key_is_down(KEY_FULLSCREEN) && !just_toggled_fullscreen)
{
if(al_get_display_flags(display) & ALLEGRO_FULLSCREEN_WINDOW)
{
al_set_display_flag(display, ALLEGRO_FULLSCREEN_WINDOW, 0);
}
else
{
al_set_display_flag(display, ALLEGRO_FULLSCREEN_WINDOW, 1);
}
just_toggled_fullscreen = 1;
}
else if (!key_is_down(KEY_FULLSCREEN) && just_toggled_fullscreen)
{
just_toggled_fullscreen = 0;
}
al_clear_to_color(al_map_rgb(0, 0, 0));
ship_draw(&ship);
if(show_info)
{
char info[256];
sprintf(info, info_format,
ship.x, ship.y,
ship.direction,
RAD_TO_DEG(ship.direction),
ship.velX * FPS, ship.velY * FPS);
al_draw_multiline_text(font,
al_map_rgb(0xFF, 0xFF, 0xFF),
5, 5, WINDOW_WIDTH, 10.0f,
ALLEGRO_ALIGN_LEFT,
info);
}
if(show_help)
{
al_draw_multiline_text(font,
al_map_rgb(0xFF, 0xFF, 0xFF),
(float)WINDOW_WIDTH / 2, (float)WINDOW_HEIGHT / 2 - 50,
WINDOW_WIDTH, 10.0f,
ALLEGRO_ALIGN_CENTRE,
help);
}
al_flip_display();
redraw = 0;
}
}
al_destroy_font(font);
evnt_mngr_deinit();
al_destroy_display(display);
#ifdef DEBUG
puts("Destroyed display.");
#endif
al_shutdown_font_addon();
#ifdef DEBUG
puts("Shutdown font addon.");
#endif
al_shutdown_primitives_addon();
#ifdef DEBUG
puts("Shutdown primitives addon.");
#endif
return 0;
}

84
src/ship.c Normal file
View File

@@ -0,0 +1,84 @@
/*
* Copyright (C) 2018 Ortega Froysa, Nicolás <nortega@themusicinnoise.net>
* Author: Ortega Froysa, Nicolás <nortega@themusicinnoise.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ship.h"
#include "event_manager.h"
#include "globals.h"
#include <math.h>
#include <assert.h>
#include <allegro5/allegro_primitives.h>
#include <stdio.h>
#define SHIP_RADIUS 10.0f // radius of the ship in pixels
void ship_init(struct ship *ship, int x, int y) {
assert(ship);
ship->x = x;
ship->y = y;
ship->velX = ship->velY = 0;
ship->direction = 0;
}
void ship_update(struct ship *ship) {
assert(ship);
if(key_is_down(KEY_RIGHT))
ship->direction += TURN_ACCEL;
if(key_is_down(KEY_LEFT))
ship->direction -= TURN_ACCEL;
// keep direction within bounds
if(ship->direction >= M_PI * 2)
ship->direction -= M_PI * 2;
else if(ship->direction < 0)
ship->direction += M_PI * 2;
if(key_is_down(KEY_UP))
{
ship->velX += cos(ship->direction) * ACCEL;
ship->velY += sin(ship->direction) * ACCEL;
}
if(key_is_down(KEY_DOWN))
{
// moving backwards is slower than moving forward
ship->velX -= cos(ship->direction) * (ACCEL / 2);
ship->velY -= sin(ship->direction) * (ACCEL / 2);
}
ship->x += ship->velX;
ship->y += ship->velY;
}
void ship_draw(struct ship *ship) {
assert(ship);
const float x0 = ship->x + (cos(ship->direction) *
SHIP_RADIUS);
const float y0 = ship->y + (sin(ship->direction) *
SHIP_RADIUS);
const float x1 = ship->x + (cos(ship->direction +
M_PI * 0.8f) * SHIP_RADIUS);
const float y1 = ship->y + (sin(ship->direction +
M_PI * 0.8f) * SHIP_RADIUS);
const float x2 = ship->x + (cos(ship->direction +
M_PI * 1.2f) * SHIP_RADIUS);
const float y2 = ship->y + (sin(ship->direction +
M_PI * 1.2f) * SHIP_RADIUS);
al_draw_filled_triangle(x0, y0, x1, y1, x2, y2,
al_map_rgb(0xFF, 0x0, 0x0));
}

55
src/ship.h Normal file
View File

@@ -0,0 +1,55 @@
/*
* Copyright (C) 2018 Ortega Froysa, Nicolás <nortega@themusicinnoise.net>
* Author: Ortega Froysa, Nicolás <nortega@themusicinnoise.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <allegro5/allegro.h>
struct ship {
float x, y; ///< The x and y coordinates of the ship.
float velX, velY; ///< The x and y velocities of the ship.
/**
* The direction that the ship is facing in radians, where
* 0 is right facing.
*/
float direction;
};
/**
* @brief Initialize the ship at a position.
*
* @param ship A pointer to the ship object.
* @param x Initial x position of the ship.
* @param y Initial y position of the ship.
*/
void ship_init(struct ship *ship, int x, int y);
/**
* @brief Updates the ship's variables according to keyboard
* input.
*
* @param ship A pointer to the ship object.
*/
void ship_update(struct ship *ship);
/**
* @brief Draw the ship.
*
* @param ship Ship object to draw.
*/
void ship_draw(struct ship *ship);

View File

@@ -1,115 +0,0 @@
package spaceshipsim;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.util.*;
import spaceshipsim.entities.*;
/**
* @author Nicolás A. Ortega
* @copyright Nicolás A. Ortega
* @license GNU GPLv3
* @year 2014
*
*/
public class SpaceShipSim extends JFrame implements Runnable, KeyListener {
private final String version = "v0.1";
private Thread gameloop;
private BufferedImage backbuffer;
private Graphics2D g2d;
private AffineTransform identity = new AffineTransform();
private Ship ship;
// Constructor:
public SpaceShipSim() {
super("Space Ship Simulator");
setSize(800, 600);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
backbuffer = new BufferedImage(800, 600, BufferedImage.TYPE_INT_RGB);
g2d = backbuffer.createGraphics();
ship = new Ship(400, 300);
addKeyListener(this);
start();
}
public void start() {
gameloop = new Thread(this);
gameloop.start();
}
public void stop() { gameloop = null; }
public void paint(Graphics g) {
g2d.setTransform(identity);
g2d.setPaint(Color.BLACK);
g2d.fillRect(0, 0, getSize().width, getSize().height);
drawInfo();
drawShip();
g.drawImage(backbuffer, 0, 0, this);
}
private void drawInfo() {
g2d.setPaint(Color.WHITE);
g2d.drawString("Welcome to SpaceShipSim " + version, 10, 40);
g2d.drawString("Position: " + (int)ship.getX() + ", " + (int)ship.getY(), 10, 55);
g2d.drawString("Velocity (px/s): " + (int)(ship.getVelX() * 50) + ", " + (int)(ship.getVelY() * 50), 10, 70);
g2d.drawString("Acceleration (px/s/s): " + (int)(ship.getAccelX() * Math.pow(50, 2)) + ", " + (int)(ship.getAccelY() * Math.pow(50, 2)), 10, 85);
g2d.drawString("Move Angle: " + (int)ship.getMoveAngle(), 10, 100);
g2d.drawString("Face Angle: " + (int)(ship.getFaceAngle() - 90), 10, 115);
}
private void drawShip() {
g2d.setTransform(identity);
g2d.translate(ship.getX(), ship.getY());
g2d.rotate(Math.toRadians(ship.getFaceAngle()));
g2d.setColor(Color.RED);
g2d.fill(ship.getShape());
}
public void run() {
Thread t = Thread.currentThread();
while(t == gameloop) {
try {
ship.update();
Thread.sleep(20);
} catch(InterruptedException ie) {
ie.printStackTrace();
}
repaint();
}
}
public void keyPressed(KeyEvent ke) {
//keys[ke.getKeyCode()] = true;
int keyCode = ke.getKeyCode();
if(keyCode == KeyEvent.VK_UP) { ship.setAccelerate(true); }
if(keyCode == KeyEvent.VK_LEFT) { ship.setTurnLeft(true); }
if(keyCode == KeyEvent.VK_RIGHT) { ship.setTurnRight(true); }
}
public void keyReleased(KeyEvent ke) {
int keyCode = ke.getKeyCode();
if(keyCode == KeyEvent.VK_UP) { ship.setAccelerate(false); }
if(keyCode == KeyEvent.VK_LEFT) { ship.setTurnLeft(false); }
if(keyCode == KeyEvent.VK_RIGHT) { ship.setTurnRight(false); }
}
public void keyTyped(KeyEvent ke) {}
public static void main(String[] args) { new SpaceShipSim(); }
}

View File

@@ -1,56 +0,0 @@
package spaceshipsim.entities;
import java.awt.Shape;
/**
* @author Nicolás A. Ortega
* @copyright Nicolás A. Ortega
* @license GNU GPLv3
* @year 2014
*
*/
public class BaseVectorShape {
private Shape shape;
private boolean alive;
private double x, y;
private double velX, velY;
private double moveAngle, faceAngle;
// Constructor:
public BaseVectorShape() {
setShape(null);
setAlive(false);
setX(0.0);
setY(0.0);
setVelX(0.0);
setVelY(0.0);
setMoveAngle(0.0);
setFaceAngle(0.0);
}
// Accessor methods:
public Shape getShape() { return shape; }
public boolean isAlive() { return alive; }
public double getX() { return x; }
public double getY() { return y; }
public double getVelX() { return velX; }
public double getVelY() { return velY; }
public double getMoveAngle() { return moveAngle; }
public double getFaceAngle() { return faceAngle; }
// Setter methods:
public void setShape(Shape shape) { this.shape = shape; }
public void setAlive(boolean alive) { this.alive = alive; }
public void setX(double x) { this.x = x; }
public void incX(double iX) { this.x += iX; }
public void setY(double y) { this.y = y; }
public void incY(double iY) { this.y += iY; }
public void setVelX(double velX) { this.velX = velX; }
public void incVelX(double iVX) { this.velX += iVX; }
public void setVelY(double velY) { this.velY = velY; }
public void incVelY(double iVY) { this.velY += iVY; }
public void setMoveAngle(double nMA) { this.moveAngle = nMA; }
public void incMoveAngle(double iMA) { this.moveAngle += iMA; }
public void setFaceAngle(double nFA) { this.faceAngle = nFA; }
public void incFaceAngle(double iFA) { this.faceAngle += iFA; }
}

View File

@@ -1,76 +0,0 @@
package spaceshipsim.entities;
import java.awt.*;
/**
* @author Nicolás A. Ortega
* @copyright Nicolás A. Ortega
* @license GNU GPLv3
* @year 2014
*
*/
public class Ship extends BaseVectorShape {
// Ship shape points for vector image
private int[] shipx = { -6, -3, 0, 3, 6, 0 };
private int[] shipy = { 6, 7, 7, 7, 6, -7 };
// Booleans for movement
private boolean accelerate = false;
private boolean turnLeft = false;
private boolean turnRight = false;
// Acceleration variables
private double accelerateX;
private double accelerateY;
// Constructor:
public Ship(double nx, double ny) {
setX(nx);
setY(ny);
setShape(new Polygon(shipx, shipy, shipx.length));
setAlive(true);
}
// Update Method:
public void update() {
if(accelerate) {
setMoveAngle(getFaceAngle() - 90);
accelerateX = calcAngleMoveX(getMoveAngle()) * 0.1;
accelerateY = calcAngleMoveY(getMoveAngle()) * 0.1;
incVelX(accelerateX);
incVelY(accelerateY);
} else {
accelerateX = 0;
accelerateY = 0;
}
if(turnLeft) {
incFaceAngle(-5);
if(getFaceAngle() < 0) { setFaceAngle(355); } // 355 = 360 - 5
}
if(turnRight) {
incFaceAngle(5);
if(getFaceAngle() > 360) { setFaceAngle(5); }
}
incX(getVelX());
incY(getVelY());
}
// Accessor methods:
public Rectangle getBounds() {
Rectangle r;
r = new Rectangle((int)getX() - 6, (int)getY() - 6, 12, 12);
return r;
}
public double getAccelX() { return accelerateX; }
public double getAccelY() { return accelerateY; }
// Setter methods:
public void setAccelerate(boolean accel) { this.accelerate = accel; }
public void setTurnLeft(boolean tL) { this.turnLeft = tL; }
public void setTurnRight(boolean tR) { this.turnRight = tR; }
// Methods used for calculations:
public double calcAngleMoveX(double angle) { return (double) (Math.cos(angle * Math.PI / 180)); }
public double calcAngleMoveY(double angle) { return (double) (Math.sin(angle * Math.PI / 180)); }
}