Collision demo for the Gameduino

Committer:
TheChrisyd
Date:
Fri Dec 21 13:50:18 2012 +0000
Revision:
1:614d0042c0d5
Parent:
0:deb284e70ca5
updated Gameduino library

Who changed what in which revision?

UserRevisionLine numberNew contents of line
TheChrisyd 0:deb284e70ca5 1
TheChrisyd 0:deb284e70ca5 2 #include "shield.h"
TheChrisyd 0:deb284e70ca5 3 #include "mbed.h"
TheChrisyd 0:deb284e70ca5 4 #include "GD.h"
TheChrisyd 0:deb284e70ca5 5 SPI spimain(ARD_MOSI, ARD_MISO, ARD_SCK); // mosi, miso, sclk
TheChrisyd 0:deb284e70ca5 6 GDClass GD(ARD_MOSI, ARD_MISO, ARD_SCK, ARD_D9, USBTX, USBRX) ;
TheChrisyd 0:deb284e70ca5 7
TheChrisyd 0:deb284e70ca5 8 void readn(int *dst, unsigned int addr, int c) {
TheChrisyd 0:deb284e70ca5 9 GD.__start(addr);
TheChrisyd 0:deb284e70ca5 10 while (c--)
TheChrisyd 0:deb284e70ca5 11 *dst++ = spimain.write(0);
TheChrisyd 0:deb284e70ca5 12 GD.__end();
TheChrisyd 0:deb284e70ca5 13 }
TheChrisyd 0:deb284e70ca5 14
TheChrisyd 0:deb284e70ca5 15 #define NBALLS 80
TheChrisyd 0:deb284e70ca5 16
TheChrisyd 0:deb284e70ca5 17 static int coll[NBALLS];
TheChrisyd 0:deb284e70ca5 18 static void load_coll() {
TheChrisyd 0:deb284e70ca5 19 while (GD.rd(VBLANK) == 0) // Wait until vblank
TheChrisyd 0:deb284e70ca5 20 ;
TheChrisyd 0:deb284e70ca5 21 while (GD.rd(VBLANK) == 1) // Wait until display
TheChrisyd 0:deb284e70ca5 22 ;
TheChrisyd 0:deb284e70ca5 23 while (GD.rd(VBLANK) == 0) // Wait until vblank
TheChrisyd 0:deb284e70ca5 24 ;
TheChrisyd 0:deb284e70ca5 25 readn(coll, COLLISION, NBALLS);
TheChrisyd 0:deb284e70ca5 26 }
TheChrisyd 0:deb284e70ca5 27
TheChrisyd 0:deb284e70ca5 28 struct ball {
TheChrisyd 0:deb284e70ca5 29 int x, y;
TheChrisyd 0:deb284e70ca5 30 signed char vx, vy;
TheChrisyd 0:deb284e70ca5 31 int lasthit;
TheChrisyd 0:deb284e70ca5 32 };
TheChrisyd 0:deb284e70ca5 33
TheChrisyd 0:deb284e70ca5 34 static struct ball balls[NBALLS];
TheChrisyd 0:deb284e70ca5 35
TheChrisyd 0:deb284e70ca5 36 #include "stone_wall_texture.h" // texture from 3dmd.net project
TheChrisyd 0:deb284e70ca5 37 #include "sphere.h"
TheChrisyd 0:deb284e70ca5 38
TheChrisyd 0:deb284e70ca5 39 static void plot_balls() {
TheChrisyd 0:deb284e70ca5 40 int i;
TheChrisyd 0:deb284e70ca5 41 for (i = 0; i < NBALLS; i++)
TheChrisyd 0:deb284e70ca5 42 GD.sprite(i, balls[i].x >> 4, balls[i].y >> 4, 0, 0, 0);
TheChrisyd 0:deb284e70ca5 43 }
TheChrisyd 0:deb284e70ca5 44
TheChrisyd 0:deb284e70ca5 45 // Place all balls so that none collide. Do this by placing all at
TheChrisyd 0:deb284e70ca5 46 // random, then moving until there are no collisions
TheChrisyd 0:deb284e70ca5 47
TheChrisyd 0:deb284e70ca5 48 static int anycolliding() {
TheChrisyd 0:deb284e70ca5 49 plot_balls();
TheChrisyd 0:deb284e70ca5 50 load_coll();
TheChrisyd 0:deb284e70ca5 51 int i;
TheChrisyd 0:deb284e70ca5 52 for (i = 0; i < NBALLS; i++)
TheChrisyd 0:deb284e70ca5 53 if (coll[i] != 0xff)
TheChrisyd 0:deb284e70ca5 54 return 1;
TheChrisyd 0:deb284e70ca5 55 return 0;
TheChrisyd 0:deb284e70ca5 56 }
TheChrisyd 0:deb284e70ca5 57
TheChrisyd 0:deb284e70ca5 58 static void place_balls() {
TheChrisyd 0:deb284e70ca5 59 int i;
TheChrisyd 0:deb284e70ca5 60 for (i = 0; i < NBALLS; i++) {
TheChrisyd 0:deb284e70ca5 61 balls[i].x = (2 + rand()%380) << 4;
TheChrisyd 0:deb284e70ca5 62 balls[i].y = (2 + rand()%280) << 4;
TheChrisyd 0:deb284e70ca5 63 balls[i].vx = (rand()%256)-128;
TheChrisyd 0:deb284e70ca5 64 balls[i].vy = (rand()%256)-128;
TheChrisyd 0:deb284e70ca5 65 balls[i].lasthit = 255;
TheChrisyd 0:deb284e70ca5 66 }
TheChrisyd 0:deb284e70ca5 67 while (anycolliding()) {
TheChrisyd 0:deb284e70ca5 68 for (i = 0; i < NBALLS; i++) {
TheChrisyd 0:deb284e70ca5 69 if (coll[i] != 0xff) {
TheChrisyd 0:deb284e70ca5 70 balls[i].x = (2 + (rand()%380)) << 4;
TheChrisyd 0:deb284e70ca5 71 balls[i].y = (2 + (rand()%280)) << 4;
TheChrisyd 0:deb284e70ca5 72 }
TheChrisyd 0:deb284e70ca5 73 }
TheChrisyd 0:deb284e70ca5 74 }
TheChrisyd 0:deb284e70ca5 75 }
TheChrisyd 0:deb284e70ca5 76
TheChrisyd 0:deb284e70ca5 77 void setup() {
TheChrisyd 0:deb284e70ca5 78 int i;
TheChrisyd 0:deb284e70ca5 79
TheChrisyd 0:deb284e70ca5 80 GD.begin();
TheChrisyd 0:deb284e70ca5 81
TheChrisyd 0:deb284e70ca5 82 GD.wr(JK_MODE, 0);
TheChrisyd 0:deb284e70ca5 83
TheChrisyd 0:deb284e70ca5 84 GD.copy(RAM_CHR, stone_wall_texture_chr, sizeof(stone_wall_texture_chr));
TheChrisyd 0:deb284e70ca5 85 GD.copy(RAM_PAL, stone_wall_texture_pal, sizeof(stone_wall_texture_pal));
TheChrisyd 0:deb284e70ca5 86 for (i = 0; i < 4096; i++)
TheChrisyd 0:deb284e70ca5 87 GD.wr(RAM_PIC + i, (i & 15) + ((i >> 6) << 4));
TheChrisyd 0:deb284e70ca5 88
TheChrisyd 0:deb284e70ca5 89 GD.copy(RAM_SPRIMG, sphere_img, sizeof(sphere_img));
TheChrisyd 0:deb284e70ca5 90 GD.copy(RAM_SPRPAL, sphere_pal, sizeof(sphere_pal));
TheChrisyd 0:deb284e70ca5 91
TheChrisyd 0:deb284e70ca5 92 for (i = 0; i < 256; i++)
TheChrisyd 0:deb284e70ca5 93 GD.sprite(i, 400, 400, 0, 0, 0);
TheChrisyd 0:deb284e70ca5 94
TheChrisyd 0:deb284e70ca5 95 place_balls();
TheChrisyd 0:deb284e70ca5 96 }
TheChrisyd 0:deb284e70ca5 97
TheChrisyd 0:deb284e70ca5 98
TheChrisyd 0:deb284e70ca5 99 float dot(float x1, float y1, float x2, float y2) {
TheChrisyd 0:deb284e70ca5 100 return (x1 * x2) + (y1 * y2);
TheChrisyd 0:deb284e70ca5 101 }
TheChrisyd 0:deb284e70ca5 102
TheChrisyd 0:deb284e70ca5 103 // Collide ball a with ball b, compute new velocities.
TheChrisyd 0:deb284e70ca5 104 // Algorithm from
TheChrisyd 0:deb284e70ca5 105 // http://stackoverflow.com/questions/345838/ball-to-ball-collision-detection-and-handling
TheChrisyd 0:deb284e70ca5 106
TheChrisyd 0:deb284e70ca5 107 void collide(struct ball *a, struct ball *b) {
TheChrisyd 0:deb284e70ca5 108 float collision_x, collision_y;
TheChrisyd 0:deb284e70ca5 109
TheChrisyd 0:deb284e70ca5 110 collision_x = a->x - b->x;
TheChrisyd 0:deb284e70ca5 111 collision_y = a->y - b->y;
TheChrisyd 0:deb284e70ca5 112 float distance = sqrt(collision_x * collision_x + collision_y * collision_y);
TheChrisyd 0:deb284e70ca5 113 float rdistance = 1.0 / distance;
TheChrisyd 0:deb284e70ca5 114 collision_x *= rdistance;
TheChrisyd 0:deb284e70ca5 115 collision_y *= rdistance;
TheChrisyd 0:deb284e70ca5 116 float aci = dot(a->vx, a->vy, collision_x, collision_y);
TheChrisyd 0:deb284e70ca5 117 float bci = dot(b->vx, b->vy, collision_x, collision_y);
TheChrisyd 0:deb284e70ca5 118 float acf = bci;
TheChrisyd 0:deb284e70ca5 119 float bcf = aci;
TheChrisyd 0:deb284e70ca5 120 a->vx += int((acf - aci) * collision_x);
TheChrisyd 0:deb284e70ca5 121 a->vy += int((acf - aci) * collision_y);
TheChrisyd 0:deb284e70ca5 122 b->vx += int((bcf - bci) * collision_x);
TheChrisyd 0:deb284e70ca5 123 b->vy += int((bcf - bci) * collision_y);
TheChrisyd 0:deb284e70ca5 124 }
TheChrisyd 0:deb284e70ca5 125
TheChrisyd 0:deb284e70ca5 126 #define LWALL (0 << 4)
TheChrisyd 0:deb284e70ca5 127 #define RWALL (384 << 4)
TheChrisyd 0:deb284e70ca5 128 #define TWALL (0 << 4)
TheChrisyd 0:deb284e70ca5 129 #define BWALL (284 << 4)
TheChrisyd 0:deb284e70ca5 130
TheChrisyd 0:deb284e70ca5 131 static int timer;
TheChrisyd 0:deb284e70ca5 132 int main() {
TheChrisyd 0:deb284e70ca5 133 setup();
TheChrisyd 0:deb284e70ca5 134 while (1) {
TheChrisyd 0:deb284e70ca5 135 int i;
TheChrisyd 0:deb284e70ca5 136
TheChrisyd 0:deb284e70ca5 137 plot_balls();
TheChrisyd 0:deb284e70ca5 138
TheChrisyd 0:deb284e70ca5 139 load_coll();
TheChrisyd 0:deb284e70ca5 140
TheChrisyd 0:deb284e70ca5 141 struct ball *pb;
TheChrisyd 0:deb284e70ca5 142
TheChrisyd 0:deb284e70ca5 143 for (i = NBALLS, pb = balls; i--; pb++, i) {
TheChrisyd 0:deb284e70ca5 144 if ((pb->x <= LWALL)) {
TheChrisyd 0:deb284e70ca5 145 pb->x = LWALL;
TheChrisyd 0:deb284e70ca5 146 pb->vx = -pb->vx;
TheChrisyd 0:deb284e70ca5 147 }
TheChrisyd 0:deb284e70ca5 148 if ((pb->x >= RWALL)) {
TheChrisyd 0:deb284e70ca5 149 pb->x = RWALL;
TheChrisyd 0:deb284e70ca5 150 pb->vx = -pb->vx;
TheChrisyd 0:deb284e70ca5 151 }
TheChrisyd 0:deb284e70ca5 152 if ((pb->y <= TWALL)) {
TheChrisyd 0:deb284e70ca5 153 pb->y = TWALL;
TheChrisyd 0:deb284e70ca5 154 pb->vy = -pb->vy;
TheChrisyd 0:deb284e70ca5 155 }
TheChrisyd 0:deb284e70ca5 156 if ((pb->y >= BWALL)) {
TheChrisyd 0:deb284e70ca5 157 pb->y = BWALL;
TheChrisyd 0:deb284e70ca5 158 pb->vy = -pb->vy;
TheChrisyd 0:deb284e70ca5 159 }
TheChrisyd 0:deb284e70ca5 160 }
TheChrisyd 0:deb284e70ca5 161 for (i = 1; i < NBALLS; i++) {
TheChrisyd 0:deb284e70ca5 162 int other = coll[i];
TheChrisyd 0:deb284e70ca5 163 if ((balls[i].lasthit != other) && other != 0xff) {
TheChrisyd 0:deb284e70ca5 164 collide(&balls[i], &balls[other]);
TheChrisyd 0:deb284e70ca5 165 }
TheChrisyd 0:deb284e70ca5 166 balls[i].lasthit = other;
TheChrisyd 0:deb284e70ca5 167 }
TheChrisyd 0:deb284e70ca5 168 for (i = NBALLS, pb = balls; i--; pb++, i) {
TheChrisyd 0:deb284e70ca5 169 pb->x += pb->vx;
TheChrisyd 0:deb284e70ca5 170 pb->y += pb->vy;
TheChrisyd 0:deb284e70ca5 171 }
TheChrisyd 0:deb284e70ca5 172 if (++timer == 2000) {
TheChrisyd 0:deb284e70ca5 173 place_balls();
TheChrisyd 0:deb284e70ca5 174 wait_ms(1000);
TheChrisyd 0:deb284e70ca5 175 timer = 0;
TheChrisyd 0:deb284e70ca5 176 }
TheChrisyd 0:deb284e70ca5 177 }
TheChrisyd 0:deb284e70ca5 178 }