home *** CD-ROM | disk | FTP | other *** search
- ///////////////////////////////////////////////////////
- // Game Programming All In One, Third Edition
- // Chapter 10 - AngularMotion
- ///////////////////////////////////////////////////////
-
- #include <stdio.h>
- #include "allegro.h"
- #include "math.h"
- #include "sprite.h"
- #include "spritehandler.h"
-
- #define PI 3.1415926535
- #define ACCELERATION 0.1f
- #define STEP 1
-
- #define MODE GFX_AUTODETECT_WINDOWED
- #define WIDTH 800
- #define HEIGHT 600
- #define BLACK makecol(0,0,0)
- #define WHITE makecol(255,255,255)
-
- //calculate X movement value based on direction angle
- double calcAngleMoveX(int angle) {
- return (double) cos(angle * PI / 180);
- }
-
- //calculate Y movement value based on direction angle
- double calcAngleMoveY(int angle) {
- return (double) sin(angle * PI / 180);
- }
-
- void erasesprite(BITMAP *dest, sprite *spr)
- {
- //erase the sprite using BLACK color fill
- rectfill(dest, (int)spr->x, (int)spr->y, (int)spr->x + spr->width,
- (int)spr->y + spr->height, BLACK);
- }
-
- void warpsprite(sprite *spr)
- {
- //simple screen warping behavior
- int w = spr->width;
- int h = spr->height;
-
- if (spr->x < 0-w)
- {
- spr->x = SCREEN_W;
- }
-
- else if (spr->x > SCREEN_W)
- {
- spr->x = 0-w;
- }
-
- if (spr->y < 0-h)
- {
- spr->y = SCREEN_H;
- }
-
- else if (spr->y > SCREEN_H)
- {
- spr->y = 0-h;
- }
-
- }
-
- int main(void)
- {
- //initialize
- allegro_init();
- set_color_depth(16);
- set_gfx_mode(MODE, WIDTH, HEIGHT, 0, 0);
- install_keyboard();
- install_timer();
- srand(time(NULL));
-
- //create a back buffer
- BITMAP *buffer = create_bitmap(WIDTH,HEIGHT);
-
- //create the ship sprite
- sprite *ship = new sprite();
- ship->load("ship.bmp");
- ship->width = 60;
- ship->height = 60;
- ship->xdelay = 0;
- ship->ydelay = 0;
- ship->x = SCREEN_W / 2;
- ship->y = SCREEN_H / 2;
- ship->moveAngle = 0;
- ship->faceAngle = 0;
-
- //game loop
- while (!key[KEY_ESC])
- {
- rectfill(buffer, 0, 0, WIDTH-1, HEIGHT-1, BLACK);
- erasesprite(buffer, ship);
-
- if (key[KEY_LEFT]) {
- ship->faceAngle -= STEP;
- if (ship->faceAngle < 0) ship->faceAngle = 359;
- }
-
- if (key[KEY_RIGHT]) {
- ship->faceAngle += STEP;
- if (ship->faceAngle > 359) ship->faceAngle = 0;
- }
-
- if (key[KEY_UP]) {
- //shift 0-degree orientation from right-face to up-face
- ship->moveAngle = ship->faceAngle - 90;
- //convert negative angle to wraparound
- if (ship->moveAngle < 0) ship->moveAngle = 359 + ship->moveAngle;
-
- //adjust velocity based on angle
- ship->velx += calcAngleMoveX(ship->moveAngle) * ACCELERATION;
- ship->vely += calcAngleMoveY(ship->moveAngle) * ACCELERATION;
-
- //keep velocity down to a reasonable speed
- if (ship->velx > 4.0) ship->velx = 4.0;
- if (ship->velx < -4.0) ship->velx = -4.0;
- if (ship->vely > 4.0) ship->vely = 4.0;
- if (ship->vely < -4.0) ship->vely = -4.0;
- }
-
- //rotate sprite with adjust for Allegro's 16.16 fixed trig
- //(256 / 360 = 0.7), then divide by 2 radians
- rotate_sprite(buffer, ship->image, (int)ship->x, (int)ship->y,
- itofix((int)(ship->faceAngle / 0.7f / 2.0f)));
-
- textout_ex(buffer, font, "AngularMotion Program (ESC to quit)", 0, 0, WHITE, -1);
- textprintf_ex(buffer, font, 0, 10, WHITE, -1, "Face angle: %d", ship->faceAngle);
- textprintf_ex(buffer, font, 0, 20, WHITE, -1, "Move angle: %d", ship->moveAngle);
- textprintf_ex(buffer, font, 0, 30, WHITE, -1, "Velocity X: %.2f", ship->velx);
- textprintf_ex(buffer, font, 0, 40, WHITE, -1, "Velocity Y: %.2f", ship->vely);
- textprintf_ex(buffer, font, 0, 50, WHITE, -1, "Position X: %.2f", ship->x);
- textprintf_ex(buffer, font, 0, 60, WHITE, -1, "Position Y: %.2f", ship->y);
-
-
- //move the ship
- ship->updatePosition();
- warpsprite(ship);
-
- //refresh the screen
- acquire_screen();
- blit(buffer, screen, 0, 0, 0, 0, WIDTH, HEIGHT);
- release_screen();
- rest(10);
- }
-
- delete ship;
- destroy_bitmap(buffer);
- allegro_exit();
- return 1;
- }
-
- END_OF_MAIN()
-
-