Chris Dick
/
Gameduino_collision_demo
Collision demo for the Gameduino
Embed:
(wiki syntax)
Show/hide line numbers
main.cpp
00001 00002 #include "shield.h" 00003 #include "mbed.h" 00004 #include "GD.h" 00005 SPI spimain(ARD_MOSI, ARD_MISO, ARD_SCK); // mosi, miso, sclk 00006 GDClass GD(ARD_MOSI, ARD_MISO, ARD_SCK, ARD_D9, USBTX, USBRX) ; 00007 00008 void readn(int *dst, unsigned int addr, int c) { 00009 GD.__start(addr); 00010 while (c--) 00011 *dst++ = spimain.write(0); 00012 GD.__end(); 00013 } 00014 00015 #define NBALLS 80 00016 00017 static int coll[NBALLS]; 00018 static void load_coll() { 00019 while (GD.rd(VBLANK) == 0) // Wait until vblank 00020 ; 00021 while (GD.rd(VBLANK) == 1) // Wait until display 00022 ; 00023 while (GD.rd(VBLANK) == 0) // Wait until vblank 00024 ; 00025 readn(coll, COLLISION, NBALLS); 00026 } 00027 00028 struct ball { 00029 int x, y; 00030 signed char vx, vy; 00031 int lasthit; 00032 }; 00033 00034 static struct ball balls[NBALLS]; 00035 00036 #include "stone_wall_texture.h" // texture from 3dmd.net project 00037 #include "sphere.h" 00038 00039 static void plot_balls() { 00040 int i; 00041 for (i = 0; i < NBALLS; i++) 00042 GD.sprite(i, balls[i].x >> 4, balls[i].y >> 4, 0, 0, 0); 00043 } 00044 00045 // Place all balls so that none collide. Do this by placing all at 00046 // random, then moving until there are no collisions 00047 00048 static int anycolliding() { 00049 plot_balls(); 00050 load_coll(); 00051 int i; 00052 for (i = 0; i < NBALLS; i++) 00053 if (coll[i] != 0xff) 00054 return 1; 00055 return 0; 00056 } 00057 00058 static void place_balls() { 00059 int i; 00060 for (i = 0; i < NBALLS; i++) { 00061 balls[i].x = (2 + rand()%380) << 4; 00062 balls[i].y = (2 + rand()%280) << 4; 00063 balls[i].vx = (rand()%256)-128; 00064 balls[i].vy = (rand()%256)-128; 00065 balls[i].lasthit = 255; 00066 } 00067 while (anycolliding()) { 00068 for (i = 0; i < NBALLS; i++) { 00069 if (coll[i] != 0xff) { 00070 balls[i].x = (2 + (rand()%380)) << 4; 00071 balls[i].y = (2 + (rand()%280)) << 4; 00072 } 00073 } 00074 } 00075 } 00076 00077 void setup() { 00078 int i; 00079 00080 GD.begin(); 00081 00082 GD.wr(JK_MODE, 0); 00083 00084 GD.copy(RAM_CHR, stone_wall_texture_chr, sizeof(stone_wall_texture_chr)); 00085 GD.copy(RAM_PAL, stone_wall_texture_pal, sizeof(stone_wall_texture_pal)); 00086 for (i = 0; i < 4096; i++) 00087 GD.wr(RAM_PIC + i, (i & 15) + ((i >> 6) << 4)); 00088 00089 GD.copy(RAM_SPRIMG, sphere_img, sizeof(sphere_img)); 00090 GD.copy(RAM_SPRPAL, sphere_pal, sizeof(sphere_pal)); 00091 00092 for (i = 0; i < 256; i++) 00093 GD.sprite(i, 400, 400, 0, 0, 0); 00094 00095 place_balls(); 00096 } 00097 00098 00099 float dot(float x1, float y1, float x2, float y2) { 00100 return (x1 * x2) + (y1 * y2); 00101 } 00102 00103 // Collide ball a with ball b, compute new velocities. 00104 // Algorithm from 00105 // http://stackoverflow.com/questions/345838/ball-to-ball-collision-detection-and-handling 00106 00107 void collide(struct ball *a, struct ball *b) { 00108 float collision_x, collision_y; 00109 00110 collision_x = a->x - b->x; 00111 collision_y = a->y - b->y; 00112 float distance = sqrt(collision_x * collision_x + collision_y * collision_y); 00113 float rdistance = 1.0 / distance; 00114 collision_x *= rdistance; 00115 collision_y *= rdistance; 00116 float aci = dot(a->vx, a->vy, collision_x, collision_y); 00117 float bci = dot(b->vx, b->vy, collision_x, collision_y); 00118 float acf = bci; 00119 float bcf = aci; 00120 a->vx += int((acf - aci) * collision_x); 00121 a->vy += int((acf - aci) * collision_y); 00122 b->vx += int((bcf - bci) * collision_x); 00123 b->vy += int((bcf - bci) * collision_y); 00124 } 00125 00126 #define LWALL (0 << 4) 00127 #define RWALL (384 << 4) 00128 #define TWALL (0 << 4) 00129 #define BWALL (284 << 4) 00130 00131 static int timer; 00132 int main() { 00133 setup(); 00134 while (1) { 00135 int i; 00136 00137 plot_balls(); 00138 00139 load_coll(); 00140 00141 struct ball *pb; 00142 00143 for (i = NBALLS, pb = balls; i--; pb++, i) { 00144 if ((pb->x <= LWALL)) { 00145 pb->x = LWALL; 00146 pb->vx = -pb->vx; 00147 } 00148 if ((pb->x >= RWALL)) { 00149 pb->x = RWALL; 00150 pb->vx = -pb->vx; 00151 } 00152 if ((pb->y <= TWALL)) { 00153 pb->y = TWALL; 00154 pb->vy = -pb->vy; 00155 } 00156 if ((pb->y >= BWALL)) { 00157 pb->y = BWALL; 00158 pb->vy = -pb->vy; 00159 } 00160 } 00161 for (i = 1; i < NBALLS; i++) { 00162 int other = coll[i]; 00163 if ((balls[i].lasthit != other) && other != 0xff) { 00164 collide(&balls[i], &balls[other]); 00165 } 00166 balls[i].lasthit = other; 00167 } 00168 for (i = NBALLS, pb = balls; i--; pb++, i) { 00169 pb->x += pb->vx; 00170 pb->y += pb->vy; 00171 } 00172 if (++timer == 2000) { 00173 place_balls(); 00174 wait_ms(1000); 00175 timer = 0; 00176 } 00177 } 00178 }
Generated on Thu Jul 14 2022 22:21:06 by 1.7.2