ECE 2036 Project

Dependencies:   mbed wave_player 4DGL-uLCD-SE

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers wall.cpp Source File

wall.cpp

00001 #include "wall.h"
00002 
00003 #include "globals.h"
00004 #include "physics.h"
00005 #include "game.h"
00006 #include "math_extra.h"
00007 
00008 Wall* create_wall(int direction, int x, int y, int length, float bounce)
00009 {
00010     // Alocate memory for wall
00011     Wall* wall = (Wall*) malloc(sizeof(Wall));
00012 
00013     // Initialize type info.
00014     // Always draw on the first frame
00015     wall->type = WALL;
00016     wall->should_draw = 1;
00017 
00018     // Set user parameters
00019     wall->direction = direction;
00020     wall->x = x;
00021     wall->y = y;
00022     wall->length = length;
00023     wall->bounce = bounce;
00024 
00025     return wall;
00026 }
00027 
00028 void do_wall(Physics* next, const Physics* curr, Wall* wall, float delta)
00029 {
00030     // Debug info
00031 //    pc.printf("wall: %d %d %d %d\r\n", wall->direction, wall->x, wall->y, wall->length);
00032 
00033     float adj, percent, contact;
00034 
00035     if (wall->direction == VERTICAL) {
00036         // Step 0: Adjust the wall location based on ball radius
00037         adj = wall->x - sgn(curr->vx)*(radius+1);
00038 
00039         // Step 1: Compute percent of motion before bounce
00040         percent = (adj - curr->px) / (curr->vx*delta);
00041 
00042         // Negative percent means we're moving away from the wall
00043         // >=100% means we don't need to bounce yet
00044         if (percent >= 0.0 && percent < 1.0) {
00045             // Compute the bounce location
00046             contact = curr->py + curr->vy*percent*delta;
00047             if (in_range(contact, wall->y, wall->y + wall->length)) {
00048                 // SGFX
00049                 redLED = 1;
00050                 speaker.PlayNote(100, 0.01, sound);
00051                 redLED = 0;
00052 
00053                 // Reverse velocity and slow down
00054                 next->vx = -wall->bounce*curr->vx;
00055 
00056                 // Adjust X position.
00057                 // This dampens the integration based on how far the ball had
00058                 // to travel before reflecting.
00059                 next->px = adj - percent*next->vx*delta;
00060             }
00061             // Draw the wall if we're close by
00062             wall->should_draw = 1;
00063         }
00064 
00065         // Make sure we aren't inside the wall
00066         if (in_range((int)curr->px, wall->x - (radius+1), wall->x + (radius+1))
00067                 && in_range((int)curr->py, wall->y, wall->y + wall->length)) {
00068             next->px = wall->x + sgn(curr->px - wall->x)*(radius+1);
00069             wall->should_draw = 1;
00070         }
00071     } else { //direction == HORIZONTAL
00072         // Same as vertical case, but swap x/y
00073         adj = wall->y - sgn(curr->vy)*(radius+1);
00074         percent = (adj - curr->py) / (curr->vy*delta);
00075         if (percent >= 0.0 && percent < 1.0) {
00076             contact = curr->px + curr->vx*percent*delta;
00077             if (in_range(contact, wall->x, wall->x + wall->length)) {
00078                 redLED = 1;
00079                 speaker.PlayNote(100, 0.01, sound);
00080                 redLED = 0;
00081                 next->vy = -wall->bounce*curr->vy;
00082                 next->py = adj - percent*next->vy*delta;
00083             }
00084             // Draw the wall if we bounce
00085             wall->should_draw = 1;
00086         }
00087         if (in_range((int)curr->py, wall->y - (radius+1), wall->y + (radius+1))
00088                 && in_range((int)curr->px, wall->x, wall->x + wall->length)) {
00089             next->py = wall->y + sgn(curr->py - wall->y)*(radius+1);
00090             wall->should_draw = 1;
00091         }
00092     }
00093 }
00094 
00095 void draw_wall(Wall* wall)
00096 {
00097     if (wall->should_draw) {
00098         int wx1, wx2, wy1, wy2;
00099         wx1 = wall->x;
00100         wy1 = wall->y;
00101         wx2 = wx1 + ((wall->direction == HORIZONTAL) ? wall->length : 0);
00102         wy2 = wy1 + ((wall->direction == VERTICAL) ? wall->length : 0);
00103         uLCD.line(wx1, wy1, wx2, wy2, WHITE);
00104 
00105         // Don't draw again unless requested
00106         wall->should_draw = 0;
00107     }
00108 }