// kawi_bawi_bo (2005. 2. 12.) // by SeungJoon Choi // erucipe@hanmail.net // // http://processing.org BImage[] kbb; int kbb_w, kbb_h; int n_players, alives; Player[] players; int wait3 = 120; void setup() { size(640, 480); background(255); ellipseMode(CENTER_RADIUS); rectMode(CENTER_RADIUS); kbb = new BImage[3]; kbb[0] = loadImage("kawi.gif"); kbb[1] = loadImage("bawi.gif"); kbb[2] = loadImage("bo.gif"); kbb_w = kbb[0].width; kbb_h = kbb[0].height; n_players = 256; alives = n_players; players = new Player[n_players]; for(int i = 0; i < n_players; i++) { players[i] = new Player(width*0.5 + (1-random(2))*width*0.75, height*0.5 + (1-random(2))*height*0.75, random(TWO_PI), i); players[i].state = (int)random(3); } for(int i = 0; i < n_players; i++) { players[i].TakeOpponent(players); } } void initSystem(int id) { for(int i = 0; i < n_players; i++) { Player player = players[i]; if(i != id) { player.x = width*0.5 + (1-random(2))*width*0.75; player.y = height*0.5 + (1-random(2))*height*0.75; player.dir = random(TWO_PI); player.state = (int)random(3); player._scale = 1; player.radius = kbb_h * players[i].factor; player.alive = true; player.level = 0; player.hc_r = (int)random(255); player.hc_g = (int)random(255); player.hc_b = (int)random(255); } else { player.level = 0; } } for(int i = 0; i < n_players; i++) { players[i].TakeOpponent(players); } } void loop() { background(255); //blur(g); for(int i = 0; i < n_players; i++) { Player player = players[i]; if(player.alive) { player.Update(players); player.Draw(); } else { player._scale *= 0.975; player.radius *= 0.975; player.Draw(); } } } class Player { Player(float _x, float _y, float _dir, int _id) { x = _x; y = _y; dir = _dir; id = _id; state = 0; factor = 0.25; if(random(1) > 0.5) { left = -kbb_w * 0.5 * factor; right = kbb_w * 0.5 * factor; } else { left = kbb_w * 0.5 * factor; right = -kbb_w * 0.5 * factor; } top = -kbb_h * factor; bottom = 0; radius = kbb_h * factor; _scale = 1; vx = 0; vy = 0; dt = 0.2; alive = true; on_game = false; opp_id = -1; level = 0; old_dc = 0; iter = 0; iter2 = 0; turn = 30; wait = 0; wait2 = 0; hc_r = (int)random(255); hc_g = (int)random(255); hc_b = (int)random(255); fpx = 0; fpy = 0; } void TakeOpponent(Player[] players) { if(opp_id > -1) return; for(int i = 0; i < players.length; i++) { Player player = players[i]; if(this != player) { if(player.opp_id == -1 && player.alive == true) { float dx = x - player.x; float dy = y - player.y; float d = sqrt(dx*dx + dy*dy); if(d < (radius + player.radius)*3 && level == player.level) { opp_id = player.id; player.opp_id = id; break; } } } } } void Update(Player[] players) { if(alives == 1) { wait3--; } if(wait3 == 0) { wait3 = 120; alives = n_players; initSystem(id); } if(opp_id == -1) TakeOpponent(players); float dcx, dcy; Player opponent = null; if(opp_id > -1) { opponent = players[opp_id]; } if(opponent != null && wait == 0) { dcx = opponent.x - x; dcy = opponent.y - y; dt = 0.25; } else { dcx = width*0.5 - x; dcy = height*0.5 - y; if(wait > 0) wait--; dt = 0.15; } if(iter > turn) { wait2 = 60 + (int)random(60); turn = 60 + (int)random(60); iter = 0; float theta = 0; if(random(1) > 0.5) theta = PI*0.25; else theta = -PI*0.25; if(!on_game) { fpx = x + 2*radius*cos(dir+theta); fpy = y + 2*radius*sin(dir+theta); if(opponent != null) { opponent.fpx = opponent.x + 2*radius*cos(dir+theta); opponent.fpy = opponent.y + 2*radius*sin(dir+theta); opponent.iter = iter; opponent.turn = turn; opponent.wait2 = wait2; } } } if(wait2 > 0) { if(!on_game && opponent != null) { dcx = fpx - x; dcy = fpy - y; wait2--; } } float dc = sqrt(dcx*dcx + dcy*dcy); float fdc = abs(dc - old_dc); if(fdc < 0.1 && opponent != null) iter++; old_dc = dc; if(dc > 0) { vx += dcx / dc; vy += dcy / dc; if(dc > 2) dir = atan2(vy, vx) + PI*0.5; x += vx*dt; y += vy*dt; vx *= 0.9; vy *= 0.9; if(opponent != null) { dcx = opponent.x - x; dcy = opponent.y - y; //stroke(255, 255, 255, 64); //line(opponent.x, opponent.y, x, y); if(sqrt(dcx*dcx+dcy*dcy) < radius + opponent.radius + 5 && iter > 10) { iter2++; dir += PI*0.1*sin(6*PI*iter2/60); on_game= true; opponent.on_game = true; if(iter2 > 60) { state = (int)random(2.9); Draw(); opponent.state = (int)random(2.9); opponent.Draw(); int win = 0; if(state == 0 && opponent.state == 2) win = 1; if(state == 1 && opponent.state == 0) win = 1; if(state == 2 && opponent.state == 1) win = 1; if(state == 0 && opponent.state == 1) win = -1; if(state == 1 && opponent.state == 2) win = -1; if(state == 2 && opponent.state == 0) win = -1; if(win > 0) { opp_id = -1; opponent.opp_id = -1; opponent.alive = false; alives--; level++; _scale *= 1.25; radius *= 1.25; on_game = false; opponent.on_game = false; hc_r = hc_r * 2/3 + opponent.hc_r / 3; hc_g = hc_g * 2/3 + opponent.hc_g / 3; hc_b = hc_b * 2/3 + opponent.hc_b / 3; wait = 30 + (int)random(60); } else if(win < 0) { opp_id = -1; opponent.opp_id = -1; alive = false; alives--; opponent.level++; opponent._scale *= 1.25; opponent.radius *= 1.25; opponent.on_game = false; on_game = false; opponent.hc_r = hc_r / 3 + opponent.hc_r * 2/3; opponent.hc_g = hc_g / 3 + opponent.hc_g * 2/3; opponent.hc_b = hc_b / 3 + opponent.hc_b * 2/3; opponent.wait = 30 + (int)random(60); } iter2 = 0; } } } } for(int i = 0; i < players.length; i++) { Player player = players[i]; if(this != player && player.alive) { float dx = x - player.x; float dy = y - player.y; float d = sqrt(dx*dx + dy*dy); if(d > 0 && d < radius*2) { float R = radius + player.radius; if(d < R) { float k = R - d; float ux = dx / d; float uy = dy / d; x += k*ux*0.5; y += k*uy*0.5; player.x += -k*ux*0.5; player.y += -k*uy*0.5; } } } } } void Draw() { noStroke(); push(); translate(x, y, 0); rotateZ(dir); scale(_scale); fill(hc_r, hc_g, hc_b); beginShape(QUADS); texture(kbb[state]); vertex(left, top, 0, 0, 0); vertex(right, top, 0, width, 0); vertex(right, bottom, 0, width, height); vertex(left, bottom, 0, 0, height); endShape(); pop(); } int state; float left, top, right, bottom, radius; float x, y, vx, vy, dt, dir, old_dc; boolean alive, on_game; int id, opp_id; int iter, iter2, wait, wait2, level, turn; float factor, _scale; float hc_r, hc_g, hc_b; float fpx, fpy; }