Loading...
137
Game
Outertale (Project Spacetime)
2 years ago

Updated Stardrake's attacks, and Astro Serf's attacks got a minor tweak.

Also made my first "game" in C++ today, a rectangle demo with arrow key control. Too late to remake Outertale, but I'll use this if I make another game.

Source code in article!


		
			// rectangular demo
// a single white rectangle appears on-screen
// you can move it around with down, left, right, and up
// while it's not moving, it grows, and while it's moving, it shrinks
#include <allegro5/allegro_primitives.h>
#include <allegro5/allegro.h>
#include <allegro5/file.h>
#include <allegro5/keyboard.h>
#include <allegro5/timer.h>
#include <math.h>
#include <stdio.h>

// systems
ALLEGRO_DISPLAY *display;
ALLEGRO_EVENT_QUEUE *event_queue;
ALLEGRO_TIMER *timer;

// display constants
const double FRAMES_PER_SECOND = 30;
const int HEIGHT = 480;
const int WIDTH = 640;

// game state
bool game_closed = false;
bool game_keys[ALLEGRO_KEY_MAX] = { 0 };
bool game_rendered = false;

// object state
int object_size = 10;
int object_x = 320;
int object_y = 240;

// functions
void game_event ();
void game_loop ();
void game_render ();
void object_draw ();
void object_tick ();

// game event function
void game_event () {
   // fprintf(stdout, "game_event();\n");
   ALLEGRO_EVENT event;
   al_wait_for_event(event_queue, &event);
   switch (event.type) {
      case ALLEGRO_EVENT_DISPLAY_CLOSE: {
         // closed game
         // fprintf(stdout, "[DISPLAY_CLOSE]\n");
         game_closed = true;
         break;
      }
      case ALLEGRO_EVENT_KEY_DOWN: {
         // key pressed
         // fprintf(stdout, "[KEY_DOWN]\n");
         game_keys[event.keyboard.keycode] = true;
         break;
      }
      case ALLEGRO_EVENT_KEY_UP: {
         // key released
         // fprintf(stdout, "[KEY_UP]\n");
         game_keys[event.keyboard.keycode] = false;
         break;
      }
      case ALLEGRO_EVENT_TIMER: {
         // game tick occured
         // fprintf(stdout, "[TIMER]\n");
         object_tick();
         break;
      }
   }
}

void game_loop () {
   // fprintf(stdout, "game_loop();\n");
   
   // handle events
   while (!al_is_event_queue_empty(event_queue)) {
      game_event();
   }

   // handle display
   if (!game_rendered) {
      game_render();
      game_rendered = true;
   }
}

// game render function
void game_render () {
   // fprintf(stdout, "game_render();\n");

   // reset display
   al_clear_to_color(al_map_rgb(0, 0, 0));

   // draw object
   object_draw();
   
   // render
   al_flip_display();
}

// object draw function
void object_draw () {
   // fprintf(stdout, "object_draw();\n");

   // draw object
   float object_half = object_size / 2;
   al_draw_filled_rectangle(object_x - object_half, object_y - object_half, object_x + object_half, object_y + object_half, al_map_rgb(255, 255, 255));
}

// object tick function
void object_tick () {
   // fprintf(stdout, "object_tick();\n");

   // handle keyboard input
   {
      // set moved
      bool moved = false;

      // moved down
      if (game_keys[ALLEGRO_KEY_DOWN]) {
         moved = true;
         object_y += 6;
      }

      // moved left
      if (game_keys[ALLEGRO_KEY_LEFT]) {
         moved = true;
         object_x -= 6;
      }

      // moved right
      if (game_keys[ALLEGRO_KEY_RIGHT]) {
         moved = true;
         object_x += 6;
      }

      // moved up
      if (game_keys[ALLEGRO_KEY_UP]) {
         moved = true;
         object_y -= 6;
      }

      // check if moved
      if (moved) {
         // object size decreases while moving
         if (object_size > 10) {
            object_size--;
         }
      } else {
         // object size increases while not moving
         if (object_size < 100) {
            object_size++;
         }
      }

      // mark unrendered
      game_rendered = false;
   }

   // constrain object position to screen
   {
      float object_half = object_size / 2;
      if (object_x - object_half < 0) {
         // object is too far left
         object_x = ceil(object_half);
      } else if (object_x + object_half > WIDTH) {
         // object is too far right
         object_x = floor(WIDTH - object_half);
      }
      if (object_y - object_half < 0) {
         // object is too far up
         object_y = ceil(object_half);
      } else if (object_y + object_half > HEIGHT) {
         // object is too far down
         object_y = floor(HEIGHT - object_half);
      }
   }
}

// entry point
int main(int argc, char **argv)
{
   // initialize allegro
   if (!al_init()) {
      fprintf(stderr, "Failed to initialize Allegro!\n");
      return -1;
   }

   if (!al_install_keyboard()) {
      fprintf(stderr, "Failed to install keyboard system!\n");
      return -1;
   }

   // create display
   display = al_create_display(WIDTH, HEIGHT);
   if (!display) {
      fprintf(stderr, "Failed to create display!\n");
      return -1;
   }

   // create event queue
   event_queue = al_create_event_queue();
   if (!event_queue) {
      fprintf(stderr, "Failed to create event queue!\n");
      return -1;
   }

   // create timer
   timer = al_create_timer(1 / FRAMES_PER_SECOND);
   if (!timer) {
      fprintf(stderr, "Failed to create timer!\n");
      return -1;
   }

   // handle all events
   al_register_event_source(event_queue, al_get_display_event_source(display));
   al_register_event_source(event_queue, al_get_keyboard_event_source());
   al_register_event_source(event_queue, al_get_timer_event_source(timer));

   // start timer
   al_start_timer(timer);

   // begin loop
   while (!game_closed) {
      game_loop();
   }

   // cleanup and exit
   al_destroy_display(display);
   return 0;
}
		
	

This source code uses Allegro 5 graphics engine.

Compiled with CMake + make!

2
1


9 comments

Loading...

Next up

Due to Gamejolt sucking really bad, I can't finish the upload of 5.04. I tried yesterday and today, and it still broken. This update fixes that new chaotic route bug introduced in 5.03.

If you want this update, go here:

https://spacey-432.itch.io/outertale

Thanks!

literally 1984

chillin' by the SYRUP cooler

Return of the pipe puzzle from SOTS, now repurposed for Petrichor! Will be in the next demo. (this pipe layout is completely temporary and for testing)

20/37 redleaf rooms decorated, dialogue and story improvements for the 2nd demo, and a simple change that I think gives the game a lot more FEELING

introducing COLORS! (each area will have a different main color, and variants for specific rooms if needed)

And now, the other character's facial expressions are done as well! All characters now have walk sprites, dialogue sounds, and facial expressions, which means I can freely write the rest of the next demo dialogue.

Big progress!!

Next demo is 56% complete

2x size facial expressions for Iver are complete! Thank you to @gamebrielvoid for the concept art.

This wolfo is the boss (of the employees) at Readleaf Industries. Wonder what they'll think of you walking into the factory unauthorized...?

@JustAnimates1210 of the OUTERTALE modding project made a google form for hiring team members!

If modding the game sounds interesting to you, then apply with the form below!

https://docs.google.com/forms/d/e/1FAIpQLSdSbMsCHi030re893ggcPB9…

If you have any more questions, ask them in the comments.

MORE dialogue sprites, this time for a previously mentioned goober. I still won't spoil anything, but they're used as Petrichor's app icon for a very good reason. This character now has the most dialogue sprites of any in the game! (26 total)

Facial expressions for another character are done! Only one character left to add faces for in the next demo.

Here's a small sample: