diff --git a/Project/Game/Game.pde b/Project/Game/Game.pde index b125fc3..88e01a7 100644 --- a/Project/Game/Game.pde +++ b/Project/Game/Game.pde @@ -1,473 +1,474 @@ import java.text.DecimalFormat; import processing.video.*; Mover mover; //The ball Cylinder cyl; //The basis of all cylinders HScrollbar hs; HScrollbar minH, maxH, minS, maxS, minB, maxB; //Capture cam; Movie cam; Canny canny; PImage img; PShape globe; PShape robot; //The vilain float depth = 2000; //the depth from the box boolean GameOver=false; //Score and histo ArrayList scores; float score; float scoreMalus = -1; int scoreTimer = 0; int prVeloFreq = 20; //The frequency at which the velocity is printed float lastScore; float veloMag; float scoreFactor = 0.5; //lastScore = scoreFactor * lastVelocity; float VilainScoreMultiplier=10;//bonus score given when killing the vilain boolean win = false; int minHistowidth = 1, maxHistowidth = 20, histowidth; float maxScore = 10, minScore=-10; float drawingFactor; // = histoHeight /(maxScore -minScore); int barChartWidth, barChartHeight, bcCubeHeight = 5; boolean mousePermittedToMove=true; //Plate size float plate_w=1000; float plate_t=plate_w/20; float x_coord, y_coord; float mX, mY; //mouse X position float xOnPlane, yOnPlane; //coordinate on 2D on the box PVector oldAngles, newAngles; float rz, rx; //rotate x and rotate z float cameraHeight; float speed=10; float radius=plate_t*4/5; DecimalFormat f = new DecimalFormat("#0.00"); DecimalFormat f2 = new DecimalFormat("#0"); DecimalFormat f3 = new DecimalFormat(""); boolean shiftMod=false; ParticleWin partW; ParticleSystem partSys=null; long previousFrame=0; float timeIntervalParticle=0.5;//seconds int margin = 15; //marge between surface int botPartHeight = 300; int setupWidth = 350; PGraphics setupPart; int topViewMargin=20; int topViewWidth = botPartHeight-2*topViewMargin; PGraphics gameSurface; PGraphics statSurface; PGraphics topView; PGraphics scoreboard; PGraphics barChart; int farAwayCounter = 0;//useless now int tooMuchTimeAway = 0;//desactivated int OneTimeOutOfFour=-1; PVector NULL_VECTOR=new PVector(0, 0, 0); PVector prevAnglesOfPlate=NULL_VECTOR; PVector anglesOfPlate=null; //SetupPart int scrollMargin = 20; int scrollHeight = 10; int scrollWidth = setupWidth-2*scrollMargin; int scrollTextMargin = 16; int minHId = 80, maxHId =130; int minSId = 20, maxSId = 242; int minBId = 60, maxBId = 220; int minHpos, maxHpos, minSpos, maxSpos, minBpos, maxBpos; void settings() { size(displayWidth, displayHeight-60, P3D); fullScreen(); x_coord=width/2; y_coord=height/2; } void setup() { mover = new Mover(); partW=new ParticleWin(mover); cyl=new Cylinder(); scores = new ArrayList(); oldAngles = new PVector(0, 0, 0); newAngles = new PVector(0, 0, 0); hs = new HScrollbar(750, height -50, 450, 20, 0.5); minH = new HScrollbar(width-setupWidth+scrollMargin/2, height - 7 * (scrollHeight+scrollMargin/2), scrollWidth, scrollHeight, ((float)(minHId))/255); maxH = new HScrollbar(width-setupWidth+scrollMargin/2, height - 6 * (scrollHeight+scrollMargin/2), scrollWidth, scrollHeight, ((float)(maxHId))/255); minS = new HScrollbar(width-setupWidth+scrollMargin/2, height - 5 * (scrollHeight+scrollMargin/2), scrollWidth, scrollHeight, ((float)(minSId))/255); maxS = new HScrollbar(width-setupWidth+scrollMargin/2, height - 4 * (scrollHeight+scrollMargin/2), scrollWidth, scrollHeight, ((float)(maxSId))/255); minB = new HScrollbar(width-setupWidth+scrollMargin/2, height - 3 * (scrollHeight+scrollMargin/2), scrollWidth, scrollHeight, ((float)(minBId))/255); maxB = new HScrollbar(width-setupWidth+scrollMargin/2, height - 2 * (scrollHeight+scrollMargin/2), scrollWidth, scrollHeight, ((float)(maxBId))/255); img = loadImage("earth.jpg"); globe = createShape(SPHERE, radius); globe.setStroke(false); globe.setTexture(img); img = loadImage("robotnik.png"); robot = loadShape("robotnik.obj"); robot.setTexture(img); gameSurface=createGraphics(width-setupWidth, height-botPartHeight, P3D); setupPart = createGraphics(setupWidth, height, P2D); topView=createGraphics(topViewWidth+2*topViewMargin, topViewWidth+2*topViewMargin, P2D); statSurface=createGraphics(3*botPartHeight, botPartHeight/3, P2D); scoreboard = createGraphics(botPartHeight-2*margin, botPartHeight-2*margin, P2D); barChartWidth = width - (botPartHeight+margin) *2 -setupWidth; barChartHeight = botPartHeight-2*margin-50; barChart = createGraphics(barChartWidth, barChartHeight, P2D); //init camera /*String[] cameras = Capture.list(); if (cameras.length == 0) { println("There are no cameras available for capture."); exit(); } else { println("Available cameras:"); for (int i = 0; i < cameras.length; i++) { //println(cameras[i]); } //If you're using gstreamer0.1 (Ubuntu 16.04 and earlier), //select your predefined resolution from the list: //cam = new Capture(this, cameras[21]); //If you're using gstreamer1.0 (Ubuntu 16.10 and later), //select your resolution manually instead: cam = new Capture(this, 640, 480, cameras[0]); cam.start(); }*/ //init camera to take a video in input cam = new Movie(this, "C:/Users/match/Documents/InfoVisuGit/Mine/BA4Project/Project/Game/testvideo.avi"); cam.loop(); canny = new Canny(setupWidth); String []args = {"Image processing window"}; PApplet.runSketch(args, canny); } void draw() { background(181, 65, 2); drawGame(); image(gameSurface, 0, 0); drawStat(); image(statSurface, 0, 0); drawScoreboard(); image(scoreboard, botPartHeight+2*margin, height-botPartHeight+margin); drawBarChart(); image(barChart, 2*botPartHeight+margin, height-botPartHeight+margin); drawTopView(); image(topView, margin, height-botPartHeight); hs.update(); hs.display(); OneTimeOutOfFour++; if ((OneTimeOutOfFour%=4)==0) { newAngles = canny.update(minHpos, maxHpos, minSpos, maxSpos, minBpos, maxBpos); if (newAngles.mag() > 0) { - newAngles.set((newAngles.x <0)? newAngles.x+180 : newAngles.x -180, newAngles.y, 0);//-179 = 1 ; 179 = -1 +-180 = 0 + //newAngles.set((newAngles.x <0)? newAngles.x+180 : newAngles.x -180, newAngles.y, 0);//-179 = 1 ; 179 = -1 +-180 = 0 + newAngles.set(-((newAngles.x <0)? newAngles.x+180 : newAngles.x -180), newAngles.y, 0);//-179 = 1 ; 179 = -1 +-180 = 0 /*float dist = PVector.dist(newAngles, oldAngles); if (dist > 20) { farAwayCounter++; } if ((dist<20 || farAwayCounter > tooMuchTimeAway)) { oldAngles = newAngles.copy(); farAwayCounter =0; }*/ } } if (newAngles.mag() > 0) { oldAngles.add(newAngles).mult(0.5); } drawSetup(); image(setupPart, width-setupWidth, 0); minH.update(); minH.display(); maxH.update(); maxH.display(); minS.update(); minS.display(); maxS.update(); maxS.display(); minB.update(); minB.display(); maxB.update(); maxB.display(); } void drawBarChart() { barChart.beginDraw(); barChart.background(242, 86, 2); barChart.fill(160, 255, 255); histowidth = (int)(hs.getPos()*(maxHistowidth-minHistowidth)+minHistowidth); int maxRect = barChartWidth / histowidth; int start = (scores.size() < maxRect)? 0 : scores.size()-maxRect; for (int i = start; i < scores.size(); ++i) { float zeroInHisto = drawingFactor * (maxScore); float posInHisto = drawingFactor * (-scores.get(i)+maxScore) ; int nbOfCube = (int)(Math.abs( zeroInHisto - posInHisto)/bcCubeHeight); for (int j = 0; j < nbOfCube; ++j) { barChart.rect((i-start)*histowidth, zeroInHisto +(zeroInHisto>posInHisto? -(j+1 ): j)* bcCubeHeight, histowidth, bcCubeHeight); } //float top = (zeroInHistoposInHisto)?zeroInHisto:posInHisto)-top; //barChart.rect((i-start)*histowidth, top, histowidth, bot); } barChart.endDraw(); } void updateScore(float points) { score += points; scores.add(score); minScore = (scoremaxScore)? score : maxScore; drawingFactor = barChartHeight/(maxScore-minScore+2); } void drawSetup() { setupPart.beginDraw(); setupPart.background(242, 86, 2); minHpos = (int)(minH.getPos()*255); maxHpos = (int)(maxH.getPos()*255); minSpos = (int)(minS.getPos()*255); maxSpos = (int)(maxS.getPos()*255); minBpos = (int)(minB.getPos()*255); maxBpos = (int)(maxB.getPos()*255); PImage blobDetection = canny.getBlobDetection(); PImage afterScharr = canny.getAfterScharr(); PImage camImg = canny.getCamImage(); setupPart.fill(0); setupPart.textSize(14); setupPart.text("MinH : "+f3.format(minHpos)+" Ideally its "+f3.format(minHId)+"\n", scrollMargin/2, 3*camImg.height+ 4*scrollMargin/2+scrollTextMargin); setupPart.text("MaxH : "+f3.format(maxHpos)+" Ideally its "+f3.format(maxHId)+"\n", scrollMargin/2, 3*camImg.height+ 4*scrollMargin/2+2*scrollTextMargin); setupPart.text("MinS : "+f3.format(minSpos)+" Ideally its "+f3.format(minSId)+"\n", scrollMargin/2, 3*camImg.height+ 4*scrollMargin/2+3*scrollTextMargin); setupPart.text("MaxS : "+f3.format(maxSpos)+" Ideally its "+f3.format(maxSId)+"\n", scrollMargin/2, 3*camImg.height+ 4*scrollMargin/2+4*scrollTextMargin); setupPart.text("MinB : "+f3.format(minBpos)+" Ideally its "+f3.format(minBId)+"\n", scrollMargin/2, 3*camImg.height+ 4*scrollMargin/2+5*scrollTextMargin); setupPart.text("MaxB : "+f3.format(maxBpos)+" Ideally its "+f3.format(maxBId)+"\n", scrollMargin/2, 3*camImg.height+ 4*scrollMargin/2+6*scrollTextMargin); setupPart.image(camImg, scrollMargin/2, scrollMargin/2); setupPart.image(blobDetection, scrollMargin/2, camImg.height+ 2*scrollMargin/2); setupPart.image(afterScharr, scrollMargin/2, 2*camImg.height+ 3*scrollMargin/2); setupPart.pushMatrix(); setupPart.stroke(0); setupPart.fill(0x808080FF); List corners = canny.getCorners(); for (PVector pv : corners) { setupPart.ellipse(scrollMargin/2+pv.x, scrollMargin/2+pv.y, 15, 15); } setupPart.stroke(255,0,0); if (!corners.isEmpty()) { lineBetweenTwoCorners(corners.get(0), corners.get(1)); lineBetweenTwoCorners(corners.get(1), corners.get(2)); lineBetweenTwoCorners(corners.get(2), corners.get(3)); lineBetweenTwoCorners(corners.get(3), corners.get(0)); } setupPart.popMatrix(); setupPart.endDraw(); } void drawScoreboard() { scoreboard.beginDraw(); scoreboard.background(242, 86, 2); scoreTimer = (scoreTimer%prVeloFreq == prVeloFreq-1) ? 0 : ++scoreTimer; veloMag = (scoreTimer == 0)? mover.velocity.mag():veloMag; scoreboard.fill(0); scoreboard.textSize(25); scoreboard.text("Total Score : \n "+f.format(score), 15, 40); scoreboard.text("Velocity : \n "+f.format(veloMag), 15, 130); scoreboard.text("Last score : \n "+f.format(lastScore), 15, 220); scoreboard.endDraw(); } void drawTopView() { topView.beginDraw(); topView.background(181, 65, 2); topView.fill(255, 230, 0); topView.rect(topViewMargin, topViewMargin, topViewWidth, topViewWidth); topView.fill(255, 255, 255); float topViewCylRad=map(cyl.cylinderBaseSize, 0, plate_w/2, 0, topViewWidth); if (partSys!=null) { for (PVector pv : partSys.cylinders) { float topViewCylX=map(pv.x, -plate_w/2, plate_w/2, topViewMargin, topViewWidth+topViewMargin); float topViewCylY=map(pv.y, -plate_w/2, plate_w/2, topViewMargin, topViewWidth+topViewMargin); topView.ellipse(topViewCylX, topViewCylY, topViewCylRad, topViewCylRad); } if (partSys.cylinders.contains(partSys.mainCyl)) { topView.fill(255, 0, 0); float topViewCylX=map(partSys.mainCyl.x, -plate_w/2, plate_w/2, topViewMargin, topViewWidth+topViewMargin); float topViewCylY=map(partSys.mainCyl.y, -plate_w/2, plate_w/2, topViewMargin, topViewWidth+topViewMargin); topView.ellipse(topViewCylX, topViewCylY, topViewCylRad, topViewCylRad); } } topView.fill(0, 0, 0); float topViewBallRad=map(radius, 0, plate_w/2, 0, topViewWidth); float topViewBallX=map(mover.location.x, -plate_w/2, plate_w/2, topViewMargin, topViewWidth+topViewMargin); float topViewBallY=map(mover.location.y, -plate_w/2, plate_w/2, topViewMargin, topViewWidth+topViewMargin); topView.ellipse(topViewBallX, topViewBallY, topViewBallRad, topViewBallRad); topView.endDraw(); } void drawStat() { statSurface.beginDraw(); statSurface.background(0, 0, 0, 0); statSurface.fill(160, 255, 200); statSurface.textSize(25); statSurface.text("Rotation X : "+f.format(rx/Math.PI*180)+"° Rotation Z : "+f.format(rz/Math.PI*180)+"° speed: "+f.format(speed/10), 5, 25); statSurface.text("Ball location : ("+f2.format(mover.location.x)+","+f2.format(mover.location.y)+")", 5, 50); statSurface.text("Ball velocity : ("+f2.format(mover.velocity.x)+","+f2.format(mover.velocity.y)+")", 5, 75); statSurface.endDraw(); } void drawGame() { gameSurface.beginDraw(); if (GameOver) { gameSurface.background(50, 65, 200); } else { gameSurface.background(100, 0, 0); } gameSurface.directionalLight(50, 100, 125, 0, 1, 0); gameSurface.ambientLight(102, 102, 102); gameSurface.pointLight(150, 150, 150, 0, -200, 0); if (!shiftMod) { mover.update(); mover.checkEdges(); if (partSys!=null) { GameOver|=mover.checkCylinderCollision(partSys.cylinders, radius, partSys.mainCyl); } //rz = map(x_coord, 0, width, -PI/3, PI/3); //rx = map(y_coord, 0, height, -PI/3, PI/3); float x = Math.max(-60, Math.min(-oldAngles.x, 60)); rx = map(x, -60, 60, -PI/3, PI/3); rz = map(oldAngles.y, -60, 60, -PI/3, PI/3); cameraHeight=400; } else { rz=0; rx=-PI/2; cameraHeight=0; } gameSurface.pushMatrix(); gameSurface.camera(0, -cameraHeight, depth, 0, -100, 0, 0, 1, 1); gameSurface.rotateX(rx); gameSurface.rotateZ(rz); gameSurface.shininess(100); gameSurface.fill(160, 255, 255); gameSurface.box(plate_w, plate_t, plate_w); //particles if (partSys!=null) { if (frameCount-previousFrame>=timeIntervalParticle*frameRate && !shiftMod) { timeIntervalParticle=random(0.2, 1.2); previousFrame=frameCount; partSys.addParticle(); } partSys.run(-(plate_t/2), PI/2); } if (partW!=null && GameOver) { partW.updateNdraw(); } if (shiftMod) { xOnPlane=map(mouseX, gameSurface.screenX(-plate_w/2, 0, 0), gameSurface.screenX(plate_w/2, 0, 0), -plate_w/2, plate_w/2); yOnPlane=map(mouseY, gameSurface.screenY(0, 0, -plate_w/2), gameSurface.screenY(0, 0, plate_w/2), -plate_w/2, plate_w/2); cyl.draw(xOnPlane, yOnPlane, -(plate_t/2), PI/2); } gameSurface.translate(mover.getX(), -(plate_t/2+radius), mover.getY()); gameSurface.fill(255, 100, 100); gameSurface.rotateX(mover.getRotX()); gameSurface.rotateZ(mover.getRotZ()); gameSurface.shape(globe); gameSurface.popMatrix(); //Draw the text gameSurface.pushMatrix(); if (shiftMod) { gameSurface.fill(0); gameSurface.textSize(50); gameSurface.text("[EDIT MOD ON]", 50, 500); } gameSurface.fill(255); gameSurface.popMatrix(); gameSurface.endDraw(); } void lineBetweenTwoCorners(PVector a, PVector b) { setupPart.line(a.x+scrollMargin/2, a.y+scrollMargin/2, b.x+scrollMargin/2, b.y+scrollMargin/2); } void mouseWheel(MouseEvent event) { float e = event.getCount(); if (e<0) { speed-=speed<=2?0:1; } else { speed+=speed>=15?0:1; } } void mouseDragged() { if (!shiftMod && mousePermittedToMove) { float d=-(mX-mouseX)*speed/10; x_coord=x_coord+d<=0?0:x_coord+d>=width?width:x_coord+d; mX=mouseX; d=(mY-mouseY)*speed/10; y_coord=y_coord+d<=0?0:y_coord+d>=height?height:y_coord+d; mY=mouseY; } } void mousePressed() { if (mouseY>height-botPartHeight) { mousePermittedToMove=false; } else { mousePermittedToMove=true; } mX = mouseX; mY = mouseY; if (shiftMod && -plate_w/2 2*radius || Math.abs(yOnPlane-mover.location.y) > 2*radius)) { partSys=new ParticleSystem(new PVector(xOnPlane, yOnPlane), mover, radius); GameOver=false; } } void keyPressed() { if (keyCode == SHIFT) { shiftMod=true; } else if (keyCode==RIGHT) { cam.play(); } else if (keyCode==LEFT) { cam.pause(); } } void keyReleased() { if (keyCode == SHIFT) { shiftMod=false; } }