guy g; Set bullets; Set badguys; Set splats; Set walls; void setup(){ size(500,500); frameRate(30); resetGame(); } void resetGame(){ g = new guy(); g.x = width/2; g.y = height/2; bullets = new HashSet(); badguys = new HashSet(); splats = new HashSet(); walls = new HashSet(); for(int i = 0; i < 5; i++){ badguys.add(new badguy(random(width),random(height))); } for(int i = 0; i < 5; i++){ float x = 100; float y = 30; if(random(1) > .5){ y = 100; x = 30; } walls.add(new wall(random(width),random(height),x,y)); } } void draw(){ background(0); Iterator j; Iterator i = bullets.iterator(); while(i.hasNext()){ bullet b = (bullet)i.next(); b.move(); b.draw(); boolean isgone = false; if(b.age()){ isgone =true; } else { j = badguys.iterator(); while(j.hasNext()){ badguy t = (badguy)j.next(); if(t.bullethit(b)){ splats.add(new splat(b,t)); isgone = true; } else { } } if(!isgone){ j = walls.iterator(); while(j.hasNext()){ wall t = (wall)j.next(); if(bullethit(t,b)){ splats.add(new splat(b,t)); isgone = true; } } } } if(isgone){ i.remove(); } } i = badguys.iterator(); while(i.hasNext()){ badguy b = (badguy)i.next(); b.move(); b.draw(); } i = badguys.iterator(); while(i.hasNext()){ badguy b = (badguy)i.next(); j = badguys.iterator(); while(j.hasNext()){ badguy b2 = (badguy)j.next(); if(b.overlap(b2)){ b.collide(b2); } } } i = badguys.iterator(); while(i.hasNext()){ badguy b = (badguy)i.next(); j = walls.iterator(); while(j.hasNext()){ wall w = (wall)j.next(); if(b.overlap(w)){ print("!!!!ouch "+b.x); b.collide(w); println(" "+b.x); } } } i = walls.iterator(); while(i.hasNext()){ wall w = (wall)i.next(); if(w.overlap(g)){ w.collide(g); } w.draw(); } i = splats.iterator(); while(i.hasNext()){ splat s = (splat)i.next(); s.draw(); } g.move(); g.testFire(); g.draw(); } class splat{ sprat parent; float xoff , yoff; splat(bullet b, sprat bg){ parent = bg; xoff = b.x - bg.x; yoff = b.y - bg.y; } void draw(){ set(round(parent.x+xoff),round(parent.y+yoff),color(255,255,0)); } } class bullet{ float x,y, xspeed, yspeed; int lifetime; bullet(float px,float py, float pxspeed, float pyspeed){ lifetime = 30; x = px; y = py; xspeed=pxspeed; yspeed=pyspeed; } void draw(){ set(round(x),round(y),color(255,255,0)); } void move(){ x += xspeed; y += yspeed; } boolean age(){ lifetime--; if(lifetime < 0) { return true; } return false; } } class wall extends sprat{ wall(float px, float py, float pw, float ph){ x = px; y = py ; w = pw; h = ph; } void draw(){ noStroke(); fill(128); // rect(x,y,w,h); } } boolean bullethit(sprat s, bullet b){ if(isin(b.x,s.x,s.x+s.w) && isin(b.y,s.y,s.y+s.h)){ return true; } return false; } class badguy extends sprat { float h = 20; float w = 20; boolean bullethit(bullet b){ if(isin(b.x,x,x+w) && isin(b.y,y,y+h)){ return true; } return false; } badguy(float px,float py){ x = px; y = py; } float MAXSPEED = 1; void draw(){ noStroke(); fill(20); // rect(x,y,w,h); } void move(){ if(x < g.x){ xs += .1; } else { xs -= .1; } if(y < g.y){ ys += .1; } else { ys -= .1; } x += xs; y+=ys; xs = bound(xs,-MAXSPEED,MAXSPEED); ys = bound(ys,-MAXSPEED,MAXSPEED); } } float bound(float val, float min, float max){ if(val < min) val = min; if(val > max) val = max; return val; } boolean isin(float val, float min, float max){ if(val >= min && val <= max)return true; return false; } class guy extends sprat { int xdir; int ydir; float speedmul = 3; guy(){ w = 20; h = 20; } //random speed offset float r(){ float r = random(-0.5,0.5); return r; } void testFire(){ if(mousePressed){ if(! (xdir == 0 && ydir ==0)){ bullets.add(new bullet(x+13,y+10,(xdir*speedmul*2)+r(),(ydir*speedmul*2)+r())); } } } void move(){ xdir=0; ydir = 0; if((x + (w/2))-mouseX < -2){ xdir = 1; } if((x + (w/2))- mouseX > 2){ xdir = -1; } if((y + (h/2))- mouseY <-2){ ydir = 1; } if((y + (h/2)) - mouseY> 2){ ydir = -1; } x+=xdir*speedmul; y+=ydir*speedmul; } void draw(){ noStroke(); //fill(128); //rect(x,y,20,20); fill(255); rect(x+2,y+7,6,6); rect(x+12,y+7,6,6); fill(0); rect(x+3+xdir,y+8+ydir,4,4); rect(x+13+xdir,y+8+ydir,4,4); } } HashMap keysNow = new HashMap(); void keyPressed(){ if (key=='r'){ resetGame(); } keysNow.put(new Character(key), new Boolean(true)); } void keyReleased(){ keysNow.put(new Character(key), new Boolean(false)); } boolean isKeyDown(char pc){ Character c = new Character(pc); Boolean b = (Boolean)keysNow.get(c); if(b == null){ return false; } return b.booleanValue(); } void spratinit(float pgrav){ rectMode(CORNER); spratGrav = pgrav; } float spratGrav = 0; class sprat { sprat(){ } float x,y,w,h,mode; float xs,ys; boolean wallbounce = true; boolean floorbounce = true; boolean ceilingbounce = true; float rebound = .5; //how much it rebounds, 1.0 = elastic float lateralfriction = .8; sprat(float px, float py, float pw, float ph){ x = px; y = py; w = pw; h = ph; } void draw(){ fill(255); stroke(0); strokeWeight(1); rect(x,y,w,h); } void move(){ ys += spratGrav; x += xs; y += ys; bounds(); } //place sprat at side it hit with rebound speed multiplier thing void bounds(){ if(wallbounce && x < 0) { x = 0; xs = abs(xs) * rebound; ys *= lateralfriction; } if(wallbounce && x+w > width) { x = width-w; xs = abs(xs) * -rebound; ys *= lateralfriction; } if(ceilingbounce && y < 0) { y = 0; ys = abs(ys) * rebound; xs *= lateralfriction; } if(floorbounce && y+h > height) { y = height-h; ys = abs(ys) * -rebound; xs *= lateralfriction; } } void collide(sprat o){ float temp; temp = o.xs; o.xs = xs; xs = temp; temp = o.ys; o.ys = ys; ys = temp; //figure out which overlap is less, and make that the point where they push out float hlap = spratOverlapHoriz(o).magnitude(); float vlap = spratOverlapVert(o).magnitude(); stroke(255,0,0); // line(0,0,x,y); // line(0,0,o.x,o.y); if(hlap < vlap){ if(x < o.x){ println("!!!a!!!"); x -= hlap;// / 2.0; o.x += hlap;// / 2.0; } else { println("!!!b!!!"); x += hlap;// / 2.0; o.x -= hlap;// / 2.0; } } else { if(y < o.y){ println("!!!c!!!"); y -= hlap;// / 2.0; o.y += hlap;// / 2.0; } else { println("!!!d!!!"); y += hlap;// / 2.0; o.y -= hlap;// / 2.0; } } stroke(0,255,0); // line(0,0,x,y); // line(0,0,o.x,o.y); } boolean overlap(sprat other){ floatRange hOverlap = spratOverlapHoriz(other); if(hOverlap == null) return false; floatRange vOverlap = spratOverlapVert(other); if(vOverlap == null){ return false; } //pixel check would go here return true; } // to see if things overlap on one dimension // we sort the 4 points. if both points of // one thing are lesser than both points of the other, // they can't be overlapping..., otherwise the overlap // is the 2nd and 3rd point floatRange spratOverlapHoriz(sprat b){ sprat a = this; floatWithRef vals[] = new floatWithRef[4]; vals[0] = new floatWithRef(a.x,a); vals[1] = new floatWithRef((a.x+a.w),a); vals[2] = new floatWithRef(b.x,b); vals[3] = new floatWithRef((b.x+b.w),b); Arrays.sort(vals); if (vals[0].src == vals[1].src){ return null; } return new floatRange(vals[1].val,vals[2].val); } floatRange spratOverlapVert(sprat b){ sprat a = this; floatWithRef vals[] = new floatWithRef[4]; vals[0] = new floatWithRef(a.y,a); vals[1] = new floatWithRef((a.y+a.h),a); vals[2] = new floatWithRef(b.y,b); vals[3] = new floatWithRef((b.y+b.h),b); Arrays.sort(vals); if (vals[0].src == vals[1].src){ return null; } return new floatRange(vals[1].val,vals[2].val); } } class floatRange{ float min, max; floatRange(float p1, float p2){ min = p1p2?p1:p2; } float magnitude(){ return abs(max-min) ; } } class floatWithRef implements Comparable{ float val; Object src; floatWithRef(float pval,Object psrc){ val = pval; src = psrc; } public int compareTo(Object o){ return int(round(val - ((floatWithRef)o).val)); } }