While I was doing this, many of my attempts just stopped (hung, crashed, etc). This was because when they collided the new generated astroids immediately also crashed into eachother. This was solved by giving each astroid an "ID" number (like a social-security/personnummer). When two astroids collide, all "offspring" will have the same "ID" and no collisions happen between the same "ID".
If you take the code below and run it, it will look like this (but random):
The code is:
ArrayList<astroid> astroids = new ArrayList<astroid>(); // Settings - how many seconds between each new astroid (1 seconds = 1 * 60) int astroid_rate = 1 * 60; int astroid_count = 60; // Size in pixel of nominal astroid float ast_size = 10; float ast_min_size = 0.25; int ast_id = 1; // Run once void setup () { frameRate(60); size(500, 500); } // Called 60 times per second void draw() { int i; // 1 new astroid every 5 seconds (60 fps * 4 sec) if (astroid_count--==0) { astroids.add(new astroid(random(0, TWO_PI), random(0.1, 2.0), random(0.5, 4), random(-0.1, 0.1), random(-150, 150), random(-150, 150), ast_id++)); // Increase rate just a little astroid_count = astroid_rate--; if (astroid_rate<30) astroid_rate=30; } // Clear screen, black background(0); // Go through all astroids (if any) and update their position for (i = 0; i<astroids.size(); i++) { astroid a = astroids.get(i); if (a.update()) { // Remove bullet, if outside screen astroids.remove(i); } } } // Class definition for the shot class astroid { // An astroid angle, speed, size, rotation float angle, speed, size, rotSpeed; float position; float rotation; float xoff, yoff; float x, y; PShape s; // The PShape object - Keeps the astroid shape float i; int id; // Constructor astroid(float _angle, float _speed, float _size, float _rotSpeed, float _xoff, float _yoff, int _id) { angle = _angle; speed = _speed; size = _size; rotSpeed = _rotSpeed; xoff = _xoff; yoff = _yoff; id = _id; if (xoff<1000) { x = 250+500*cos(angle)+xoff; y = 250+500*sin(angle)+yoff; } else { x = _xoff-2000; y = _yoff-2000; } rotation = 0; // Generate the shape of the astroid - Some variations for all s = createShape(); s.beginShape(); s.fill(255, 255, 100); s.noStroke(); for (i=0; i<TWO_PI; i=i+PI/(random(4, 11))) { s.vertex(random(ast_size*0.8, ast_size*1.2)*cos(i), random(ast_size*0.8, ast_size*1.2)*sin(i)); } s.endShape(CLOSE); } // Update position, return true when out of screen boolean update() { int i; x = x - cos(angle)*speed; y = y - sin(angle)*speed; rotation = rotation + rotSpeed; // Check for astroid vs astroid collision for (i = 0; i<astroids.size(); i++) { astroid a = astroids.get(i); // If we are not our own astroid, check collision if ((a != this) && (a.coll(x, y, ast_size*size, id))) { // if size is too small, do not generate new astroid if (size > ast_min_size) { astroids.add(new astroid(angle-random(PI/5, PI/7), speed+random(0, speed/2), size/2, rotSpeed, 2000+x, 2000+y, id)); astroids.add(new astroid(angle+random(PI/5, PI/7), speed+random(0, speed/2), size/2, rotSpeed, 2000+x, 2000+y, id)); } astroids.remove(i); } } pushMatrix(); // Set position as the new 0,0 translate(x, y); // Rotate screen "angle" rotate(rotation); // Draw astroid scale(size); shape(s, 0, 0); // Bring back normal perspektive popMatrix(); if (x<-300 || x>800 || y<-300 || y>800) { return true; } else { return false; } } // Detect collision between this astroid and the one passed in boolean coll(float _x, float _y, float _size, int _id) { float dist; dist = sqrt ((x-_x)*(x-_x) + (y-_y)*(y-_y)); // Check if distance is shorter than astroid size and other objects size // No collision if the ID is same for both astroids if ((dist<(_size+ast_size*size)) && (id!=_id)) { // Collision, set the ID to the same so we do not call over and over again if (_id>0) id = _id; if (size > 1) { // If the astroid was "large" generate two new fragments astroids.add(new astroid(angle-random(PI/5, PI/7), speed+random(0, speed/2), size/2, rotSpeed, 2000+x, 2000+y, id)); astroids.add(new astroid(angle+random(PI/5, PI/7), speed+random(0, speed/2), size/2, rotSpeed, 2000+x, 2000+y, id)); } return true; } else { return false; } } }See what happens if you change these variables. Like setting this:
// Size in pixel of nominal astroid float ast_size = 20; float ast_min_size = 0.1;
In the actual game, we probably will use "ast_min_size=1" or so to not make it impossible :)
No comments:
Post a Comment