Advertisement
Guest User

Untitled

a guest
May 25th, 2016
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 34.34 KB | None | 0 0
  1. // --------------------
  2. //CORRIGIR BOOLEANS EXTRAS E OTIMIZAR FONTS, criar no setup e utilizar no textsettings como PFont
  3. // --------------------
  4. // Colored Lines Game - Part 5 (E)
  5. // --------------------
  6. // Laboratório de Programação
  7. // 19 a X de Maio 2016
  8. // Autor: Ricardo Daniel Tavares Reais
  9. // ID Mooshak: Ricardo_Reais_52333
  10. // --------------------
  11. // Window Resolution
  12. final int myWidth = 700;
  13. final int myHeight = 600;
  14. // Margin
  15. final int marginWidth = 100;
  16. final int marginHeight = 100;
  17. // Game Board Resolution
  18. int myRows = 8;
  19. int myColumns = 10;
  20. float cellWidth = (myWidth - 2.0*marginWidth)/myColumns;
  21. float cellHeight = (myHeight - 2.0*marginHeight)/myRows;
  22. // Matrix
  23. int [][] board;
  24. int [][] distance;
  25. int [][] path;
  26. int [][] temporary; //Matrix for storing balls that will be deleted (5 or more Balls sequence)
  27. int [] adjacent; //Stores the distances near to one position
  28. int [] colors; //Stores the colors need to use
  29. int [] scannedColors;
  30. // Axis Points
  31. int cell; //Ball cell
  32. int cellX, cellY; //Ball cell coordinates
  33. float cellCenterX, cellCenterY; //Ball cell center
  34. int temporaryCellX, temporaryCellY; //Ball moving animation path coordinates
  35. int previousCellColor; //Last ball clicked color
  36. int pathSize=0; //The amount of cells the ball will need to move to reach the final position (Ball animation)
  37. // Colors
  38. color windowColor;
  39. // Mouse
  40. float x, y;
  41. float movedX, movedY;
  42. int myMouseX, myMouseY; //Mouse coordinates
  43. boolean mouseClick; //1st mouse click is false, 2nd mouse click is true
  44. // Flags
  45. boolean generateRandoms; //After the mouse is clicked the second time, we have permission to generate Randoms
  46. boolean delete; //Permission to delete
  47. boolean deleting; //We have one or more sequences on the matrix that need to be deleted (Block mouse actions)
  48. // Timer
  49. final int delay = 1000; //Wainting time in milliseconds
  50. int t1 = 0; //Mouse click time
  51. int animationTime = 0; //Ball animation total time
  52. int animationSpeed = 50; //Ball animation speed for each cell jump
  53. int t2 = 0; //2nd mouse click time
  54.  
  55. int points=0;
  56. boolean start;
  57. boolean selection;
  58. boolean gameplay;
  59. boolean end;
  60. boolean saved;
  61.  
  62. boolean option1;
  63. boolean option2;
  64. boolean option3;
  65. boolean option4;
  66. boolean option5;
  67. boolean option6;
  68.  
  69. boolean medium;
  70. boolean hard;
  71.  
  72. String boardSize = "8x10";
  73. String colorNumber = "6 Colors";
  74. String difficulty = "Medium";
  75.  
  76. import com.onlylemi.processing.android.capture.*;
  77.  
  78. AndroidCamera ac;
  79.  
  80.  
  81. int boardThickness = 3;
  82. int blocks=0;
  83. PFont openingFont;
  84. PFont titleFont;
  85. PFont textFont;
  86. PFont textFontLarge;
  87. PFont timerFont;
  88.  
  89. int t3=0;
  90. int[] highscore;
  91. int[] score;
  92.  
  93. int scanCountdown=0;
  94. int scanT1=0;
  95. int c1=0;
  96. int c2=0;
  97. int c3=0;
  98.  
  99. boolean doneColor1;
  100. boolean doneColor2;
  101. boolean doneColor3;
  102.  
  103.  
  104. // -----------------
  105. void settings()
  106. {
  107. size(myWidth, myHeight); //Window resolution
  108. }
  109. // -----------------
  110. void setup()
  111. {
  112. ellipseMode(CENTER);
  113. rectMode(CENTER);
  114. textAlign(CENTER, CENTER);
  115. windowColor = white;
  116.  
  117. ac = new AndroidCamera(width, height, 20);
  118. ac.start();
  119.  
  120. start=true;
  121.  
  122. colors = myColors6;
  123.  
  124. openingFont = createFont("Disolve_regular.ttf", 100);
  125. titleFont = createFont("Disolve_regular.ttf", 50);
  126. textFont = createFont("coolvetica rg.ttf", 20);
  127. textFontLarge = createFont("coolvetica rg.ttf", 40);
  128. timerFont = createFont("DS-DIGI.TTF", 20);
  129. textSettings(white, titleFont);
  130.  
  131. // Load text file as a string
  132. String[] data = loadStrings("data.txt");
  133. printArray(data);
  134. score = new int [1];
  135. scannedColors = new int [3];
  136. // Convert string into an array of integers using ',' as a delimiter
  137. highscore = int(split(data[0],','));
  138.  
  139. }
  140. // -----------------
  141. void draw()
  142. {
  143. background(51); //51 is dark grey
  144. // Update mouse values
  145. x=mouseX;
  146. y=mouseY;
  147. movedX = mouseX;
  148. movedY = mouseY;
  149.  
  150.  
  151. if (start)
  152. startScreen();
  153. else if (selection)
  154. selectionScreen();
  155. if (option1)
  156. {
  157. if(!spaceLeft(board, 3))
  158. end=true;
  159. gameplayScreen();
  160. }
  161. if (option3)
  162. {
  163. scanScreen();
  164. }
  165. if (option4)
  166. optionScreen("Select the board size", "16x20", "8x10", "4x5");
  167. if (option5)
  168. optionScreen("Select the number of colors", "3", "6", "9");
  169. if (option6)
  170. optionScreen("Select the difficulty", "Easy", "Medium", "Hard");
  171. if (end) //No space left
  172. endScreen();
  173.  
  174. optionsMoved();
  175. timer();
  176. }
  177. // -----------------
  178. // Settings
  179. void lineSettings(color strokeColor, int strokeSize)
  180. {
  181. stroke(strokeColor);
  182. strokeWeight(strokeSize);
  183. }
  184.  
  185. void textSettings(color textColor, PFont textFont)
  186. {
  187. textFont(textFont);
  188. fill(textColor); //Text Color
  189. }
  190.  
  191. void boxSettings(boolean fill, color boxColor, boolean stroke, color strokeColor, int strokeSize, int opacity)
  192. {
  193. noFill();
  194. noStroke();
  195. if (fill)
  196. fill(boxColor, opacity);
  197. if (stroke)
  198. stroke(strokeColor);
  199. strokeWeight(strokeSize);
  200. }
  201. // -----------------
  202. // Layers
  203. void title()
  204. {
  205. textSettings(red, openingFont);
  206. text("C", 100, myHeight/2);
  207. textSettings(blue, openingFont);
  208. text("o", 125, myHeight/2);
  209. textSettings(lawngreen, openingFont);
  210. text("l", 160, myHeight/2);
  211. textSettings(magenta, openingFont);
  212. text("o", 200, myHeight/2);
  213. textSettings(magenta, openingFont);
  214. text("r", 250, myHeight/2);
  215. textSettings(yellow, openingFont);
  216. text("e", 290, myHeight/2);
  217. textSettings(orange, openingFont);
  218. text("d", 350, myHeight/2);
  219. textSettings(purple, openingFont);
  220. text(" L", 400, myHeight/2);
  221. textSettings(pink, openingFont);
  222. text("i", 460, myHeight/2);
  223. textSettings(cyan, openingFont);
  224. text("n", 500, myHeight/2);
  225. textSettings(red, openingFont);
  226. text("e", 550, myHeight/2);
  227. textSettings(blue, openingFont);
  228. text("s", 600, myHeight/2);
  229. }
  230.  
  231. void smallTitle()
  232. {
  233. textSettings(red, titleFont);
  234. text("C", 125, 50);
  235. textSettings(blue, titleFont);
  236. text("o", 150, 50);
  237. textSettings(lawngreen, titleFont);
  238. text("l", 175, 50);
  239. textSettings(magenta, titleFont);
  240. text("o", 200, 50);
  241. textSettings(magenta, titleFont);
  242. text("r", 225, 50);
  243. textSettings(yellow, titleFont);
  244. text("e", 250, 50);
  245. textSettings(orange, titleFont);
  246. text("d", 275, 50);
  247. textSettings(purple, titleFont);
  248. text(" L", 300, 50);
  249. textSettings(pink, titleFont);
  250. text("i", 325, 50);
  251. textSettings(cyan, titleFont);
  252. text("n", 350, 50);
  253. textSettings(red, titleFont);
  254. text("e", 375, 50);
  255. textSettings(blue, titleFont);
  256. text("s", 400, 50);
  257. }
  258.  
  259. void scanScreen()
  260. {
  261. int timepassed = millis()-scanT1;
  262. int timepassed2 = (millis()-scanCountdown)/1000;
  263. int c = ac.getColor(); //Current color
  264. int countdown=10;
  265.  
  266. if(timepassed2<10)
  267. {
  268. countdown -= timepassed2;
  269. textSettings(white, textFontLarge);
  270. text("Get ready to scan...\n" + countdown, myWidth/2, 45);
  271. }
  272.  
  273.  
  274. if(timepassed<15000 && timepassed>=10000)
  275. {
  276. countdown = 15 - timepassed2;
  277. textSettings(white, textFontLarge);
  278. text("Scanning color one\n" + countdown, myWidth/2, 45);
  279. c1=c;
  280. doneColor1=true;
  281. }
  282. if(timepassed<20000 && timepassed>=15000)
  283. {
  284. countdown = 20 - timepassed2;
  285. textSettings(white, textFontLarge);
  286. text("Scanning color two\n" + countdown, myWidth/2, 45);
  287. c2=c;
  288. doneColor2=true;
  289. }
  290. if(timepassed<25000 && timepassed>=20000)
  291. {
  292. countdown = 25 - timepassed2;
  293. textSettings(white, textFontLarge);
  294. text("Scanning color three\n" + countdown, myWidth/2, 45);
  295. c3=c;
  296. doneColor3=true;
  297. }
  298. if(timepassed<30000 && timepassed>=25000)
  299. {
  300. scannedColors[0]=c1;
  301. scannedColors[1]=c2;
  302. scannedColors[2]=c3;
  303. colors=scannedColors;
  304. textSettings(white, textFontLarge);
  305. text("Done Scanning", myWidth/2, 50);
  306. }
  307. if(timepassed>=30000)
  308. {
  309. gameSetup();
  310. selection=false;
  311. option3=false;
  312. option1=true;
  313. t3=millis();
  314. }
  315.  
  316.  
  317. fill(c);
  318. rect(myWidth/2, myHeight/3, 150, 150);
  319. /*
  320. if(doneColor1)
  321. {
  322. boxSettings(false, 0, true, lawngreen, 6, 255);
  323. rect(myWidth/4, myHeight/2, 150, 150);
  324. }
  325. */
  326. fill(c1);
  327. rect(myWidth/4, 2*myHeight/3 - 20, 150, 150);
  328. fill(c2);
  329. rect(myWidth/2, 2*myHeight/3 - 20, 150, 150);
  330. fill(c3);
  331. rect(3*myWidth/4, 2*myHeight/3 - 20, 150, 150);
  332. }
  333.  
  334. void startScreen()
  335. {//red, blue, lawngreen, magenta, yellow, orange, purple, pink, cyan
  336. title();
  337. }
  338.  
  339. void selectionScreen()
  340. {
  341. textSettings(white, textFontLarge);
  342. text("Select the mode", myWidth/2, 50);
  343. textSettings(white, textFont);
  344. boxSettings(false, 0, true, white, 3, 255);
  345. rect(myWidth/4, myHeight/3, 150, 150);
  346. text("Classic Mode", myWidth/4, myHeight/3);
  347.  
  348. rect(myWidth/2, myHeight/3, 150, 150);
  349. text("Android Mode", myWidth/2, myHeight/3);
  350.  
  351. rect(3*myWidth/4, myHeight/3, 150, 150);
  352. text("Color Scanner", 3*myWidth/4, myHeight/3);
  353.  
  354. rect(myWidth/4, 2*myHeight/3 - 20, 150, 150);
  355. text("Board size", myWidth/4, 2*myHeight/3 - 20);
  356.  
  357. rect(myWidth/2, 2*myHeight/3 - 20, 150, 150);
  358. text("Number\nof colors", myWidth/2, 2*myHeight/3 - 20);
  359.  
  360. rect(3*myWidth/4, 2*myHeight/3 - 20, 150, 150);
  361. text("Difficulty", 3*myWidth/4, 2*myHeight/3 - 20);
  362.  
  363. text("Settings:\n"+boardSize+"\n"+colorNumber+"\n"+difficulty, myWidth/2, myHeight - 80);
  364. }
  365.  
  366. void optionScreen(String title, String firstBox, String secondBox, String thirdBox)
  367. {
  368. textSettings(white, textFontLarge);
  369. text(title, myWidth/2, 50);
  370. textSettings(white, textFont);
  371. boxSettings(false, 0, true, white, 3, 255);
  372. rect(myWidth/4, myHeight/2, 150, 150);
  373. text(firstBox, myWidth/4, myHeight/2);
  374.  
  375. rect(myWidth/2, myHeight/2, 150, 150);
  376. text(secondBox, myWidth/2, myHeight/2);
  377.  
  378. rect(3*myWidth/4, myHeight/2, 150, 150);
  379. text(thirdBox, 3*myWidth/4, myHeight/2);
  380. }
  381. void timer()
  382. {
  383. int seconds = millis()/1000 % 60;
  384. int minutes = millis()/(1000*60) % 60;
  385. text("Time:", myWidth-75, 75);
  386. text(nf(minutes,2,0)+":"+nf(seconds,2,0), myWidth-30, 75); // nf(number, leftDigits, rightDigits) Changes number format
  387. }
  388.  
  389.  
  390. void gameplayScreen()
  391. {
  392. drawBoard();
  393. drawBlocks();
  394. drawCircle(colors);
  395. //drawBoardValues();
  396. smallTitle();
  397.  
  398. textSettings(white, timerFont);
  399. text("Points:"+points, myWidth-50, 50);
  400. timer();
  401. update();
  402.  
  403. if (millis()-t3 >= animationTime) //Draw animation,t3 is when the game starts, animation time counts
  404. pathAnimation();
  405. if (millis() >= t1 + delay) //Delete waiting time since last click
  406. delete=true; //Deletes circles if there's a sequence of 5 or more of the same color (same value)
  407. else if (millis() >= t2 + pathSize*animationSpeed && generateRandoms && !deleting && !delete) //Only add 3 random balls, after the path animation has ended and the matrix does not need to delete something
  408. {
  409. fillRandom(3);
  410. generateRandoms=false; //Not allowed to generate more randoms
  411. }
  412. }
  413.  
  414. void endScreen()
  415. {
  416. option1=false;
  417. drawBoard();
  418. drawBlocks();
  419. drawCircle(colors);
  420.  
  421. if(points > highscore[0] && !saved)
  422. {
  423. score[0]=points;
  424. String[] s = str(score);
  425. saveStrings("data.txt", s);
  426. saved=true;
  427. }
  428.  
  429. textSettings(white, textFontLarge);
  430. text("High Score:"+highscore[0]+"\nScore:"+points, myWidth/2, 50);
  431.  
  432. text("Game Over", myWidth/2, myHeight-50);
  433. }
  434. // -----------------
  435. // Draws
  436. void drawBoard()
  437. {
  438. lineSettings(white, boardThickness);
  439. for (int i = 0; i<=myColumns; i++)
  440. line(i*cellWidth + marginWidth, marginHeight, i*cellWidth + marginWidth, myRows*cellHeight + marginHeight);
  441. for (int i = 0; i<=myRows; i++)
  442. line(marginWidth, i*cellHeight + marginHeight, myColumns*cellWidth+marginWidth, i*cellHeight + marginHeight);
  443. }
  444. /*shapeMode(CENTER);
  445. void polygon(float x, float y, float radius, int npoints) {
  446. float angle = TWO_PI / npoints;
  447. beginShape();
  448. for (float a = 0; a < TWO_PI; a += angle) {
  449. float sx = x + cos(a) * radius;
  450. float sy = y + sin(a) * radius;
  451. vertex(sx, sy);
  452. }
  453. endShape(CLOSE);
  454. }
  455. */
  456. void drawCircle(int[] colors)
  457. {
  458. noStroke();
  459. for (int i = 0; i<myRows; i++)
  460. for (int j = 0; j<myColumns; j++)
  461. if (board[i][j]>0 && board[i][j]!=404)
  462. {
  463. fill(colors[board[i][j]-1]);
  464. getCellCenter(j, i, cellWidth, cellHeight, marginWidth, marginHeight); //Gets the exact cell center position
  465. if (i == cellY && j == cellX && mouseClick)
  466. ellipse(cellCenterX, cellCenterY, cellWidth*0.75 - boardThickness, cellHeight*0.75 - boardThickness);//polygon(cellCenterX, cellCenterY, cellWidth*0.75-20, 8);
  467. else
  468. ellipse(cellCenterX, cellCenterY, cellWidth - boardThickness, cellHeight - boardThickness);//polygon(cellCenterX, cellCenterY, cellWidth-26, 8);
  469. }
  470. }
  471. /*
  472. void drawBoardValues()
  473. {
  474. textSettings(white, 20, font2);
  475. for (int i = 0; i<myRows; i++)
  476. for (int j = 0; j<myColumns; j++)
  477. {
  478. getCellCenter(j, i, cellWidth, cellHeight, marginWidth, marginHeight); //Gets the exact cell center position
  479. text(board[i][j],cellCenterX, cellCenterY);//polygon(cellCenterX, cellCenterY, cellWidth*0.75-20, 8);
  480. }
  481. }
  482. */
  483. void drawBlocks()
  484. {
  485. noStroke();
  486. fill(white);
  487. for (int i = 0; i<myRows; i++)
  488. for (int j = 0; j<myColumns; j++)
  489. if (board[i][j]==404)
  490. {
  491. getCellCenter(j, i, cellWidth, cellHeight, marginWidth, marginHeight); //Gets the exact cell center position
  492. rect(cellCenterX, cellCenterY, cellWidth, cellHeight);
  493. }
  494. }
  495. // -----------------
  496. // Math
  497. void getMouseAxis(float x, float y, float w, float h, int marginWidth, int marginHeight) //Obtains the matrix coordinates of the mouse
  498. {
  499. myMouseX = int((x-marginWidth)/w);
  500. myMouseY = int((y-marginHeight)/h);
  501. }
  502.  
  503. void getCellAxis(float x, float y, float w, float h, int marginWidth, int marginHeight) //Obtains the matrix coordinates of a cell
  504. {
  505. cellX = int((x-marginWidth)/w);
  506. cellY = int((y-marginHeight)/h);
  507. }
  508.  
  509. void getCellCenter(float x, float y, float w, float h, int marginWidth, int marginHeight) //Obtains the exact center values of a cell
  510. {
  511. cellCenterX = x*w + marginWidth + w/2.0;
  512. cellCenterY = y*h + marginHeight + h/2.0;
  513. }
  514.  
  515. int getCell(float x, float y, float w, float h, int c, int marginWidth, int marginHeight) //getCell version2, recognizes a margin
  516. {
  517. int x0 = int((x-marginWidth)/w);
  518. int y0 = int((y-marginHeight)/h);
  519. cell = (y0*c)+x0;
  520. return cell;
  521. }
  522. // -----------------
  523. // Game Engine
  524. void gameSetup()
  525. {
  526. board = new int[myRows][myColumns];
  527. distance = new int[myRows][myColumns]; //Matrix with the distance values (-1 means inaccessible)
  528. path = new int [myRows][myColumns];
  529. temporary = new int[myRows][myColumns]; // Matrix for storing balls that will be deleted (5 or more Balls sequence)
  530. adjacent = new int [4]; //Stores the distances near to one position
  531. matrixSetup(distance, -1); //Fills the matrix with the value -1
  532.  
  533. fillRandom(3); //gameplay the board with 3 random balls
  534. fillRandomBlocks(blocks);
  535. }
  536.  
  537. void valueSwitcher(int[][] m, int rows, int columns, int n, int newX, int r, int c, int dv, int dh) //Deletes a sequence of same color pieces
  538. {
  539. while (r>=0 && c>=0 && r<=rows-1 && c<=columns-1 && n>0) //If we are inside the game board and the color hasn't changed
  540. {
  541. m[r][c]=newX; //Switches value in the current position
  542. r+=dv; //Moves vertically again
  543. c+=dh; //Moves horizontally again
  544. n--;
  545. }
  546. }
  547. void update()
  548. {
  549. int countS, countE, countSE, countNE; //Counts a sequence of same color pieces in every direction (needed)
  550. matrixSetup(temporary, 0); //Reset the temporary matrix
  551. for (int i = 0; i<myRows; i++)
  552. for (int j = 0; j<myColumns; j++)
  553. if (previousCellColor!=0)
  554. {
  555. //Note: we only verify 4 directions because, when we verify cell (0,0) east we are also verifying cell (5,0) west
  556. countS = countWhile(board, myRows, myColumns, previousCellColor, i, j, 1, 0); //SOUTH
  557. countE = countWhile(board, myRows, myColumns, previousCellColor, i, j, 0, 1); //EAST
  558. countSE = countWhile(board, myRows, myColumns, previousCellColor, i, j, 1, 1); //SOUTH EAST
  559. countNE = countWhile(board, myRows, myColumns, previousCellColor, i, j, -1, 1); //NORTH EAST
  560. if (countS>4) //Vertical line
  561. valueSwitcher(temporary, myRows, myColumns, countS, 1, i, j, 1, 0); //We have to add 1
  562. if (countE>4) //Diagonal line
  563. valueSwitcher(temporary, myRows, myColumns, countE, 1, i, j, 0, 1);
  564. if (countSE>4) //Vertical line
  565. valueSwitcher(temporary, myRows, myColumns, countSE, 1, i, j, 1, 1);
  566. if (countNE>4) //Diagonal line
  567. valueSwitcher(temporary, myRows, myColumns, countNE, 1, i, j, -1, 1);
  568. }
  569. if (delete) //If we have permission to delete (Delay time may change this permission)
  570. deleteMatrix();
  571. deleting = isDeleting(); //Check if something needs to be deleted, Note: something may need to be deleted and we don't have permission to delete it (yet)
  572. }
  573.  
  574. boolean isDeleting() //In the temporary matrix, each cell with the value 1 belongs to a sequence, so if we have a sequence something needs to be deleted
  575. {
  576. boolean result=false;
  577. for (int i = 0; i<myRows; i++)
  578. for (int j = 0; j<myColumns; j++)
  579. if (temporary[i][j]==1)
  580. result=true;
  581. return result;
  582. }
  583.  
  584. void deleteMatrix() //In the temporary matrix, each cell with the value 1 is deleted, because it belongs to a sequence
  585. {
  586. for (int i = 0; i<myRows; i++)
  587. for (int j = 0; j<myColumns; j++)
  588. if (temporary[i][j]==1)
  589. {
  590. points++;
  591. board[i][j]=0;
  592. }
  593. }
  594.  
  595. void matrixSetup(int[][] m, int x) //gameplays up a matrix with the value x in every position
  596. {
  597. for (int i = 0; i<myRows; i++)
  598. for (int j = 0; j<myColumns; j++)
  599. m[i][j]=x;
  600. }
  601.  
  602. int countWhile(int[][] m, int rows, int columns, int x, int r, int c, int dv, int dh) //Counts while the color doesn't change in one direction
  603. {
  604. int result=0;
  605. while (r>=0 && c>=0 && r<=rows-1 && c<=columns-1 && m[r][c]==x) //If we are inside the game board and the color hasn't changed
  606. {
  607. result++; //Confirms another same color piece on the board
  608. r+=dv; //Moves vertically again
  609. c+=dh; //Mover horizontally again
  610. }
  611. return result;
  612. }
  613.  
  614. void pathAnimation() //Creates the illusion of a moving ball (ball jumps from cell to cell at a certain animationSpeed)
  615. {
  616. animationTime+=animationSpeed; //Each cell movement adds to the animationTime
  617. sPath(path, temporaryCellY, temporaryCellX); //Begin to check if we have adjacent path
  618. }
  619.  
  620. void distances(int[][] m, int rows, int columns, int r, int c, int[][] d) //Generate all distances, gameplaying from the cell [r][c]
  621. {
  622. d[r][c]=0; //Clicked position is the gameplay
  623. int x=0; //Distance gameplays at zero
  624. int loop=0;
  625. while (loop<rows*columns) //(Optimize)
  626. {
  627. for (int i = 0; i < rows; i++)
  628. for (int j = 0; j < columns; j++)
  629. if (d[i][j]==x) //Calculate the distance to (r,c)
  630. {
  631. S(m, d, i, j, x);
  632. N(m, d, i, j, x);
  633. E(m, d, i, j, x);
  634. W(m, d, i, j, x);
  635. }
  636. loop++;
  637. x++; //Next distance
  638. }
  639. }
  640.  
  641. void shortestPath(int [][] d, int r, int c, int[][] p) //Generate the shortest path possible
  642. {
  643. int currentDistance = d[r][c];
  644. while (currentDistance>=1)
  645. {
  646. p[r][c]=1;
  647. int direction=-1; //currentDistance direction is -1
  648. sDistance(d, r, c); //southCell direction is 0
  649. nDistance(d, r, c); //northCell direction is 1
  650. eDistance(d, r, c); //eastCell direction is 2
  651. wDistance(d, r, c); //westCell direction is 3
  652. for (int i = 0; i < 4; i++) //Checks the lowest distance available
  653. if (currentDistance>adjacent[i] && adjacent[i] >=0)
  654. {
  655. currentDistance=adjacent[i];
  656. direction = i;
  657. }
  658. if (currentDistance!=0)
  659. {
  660. if (direction==-1) //If the lowest distance is the current, stay
  661. p[r][c]=1;
  662. if (direction==0) //If the lowest distance is south, move south
  663. p[r++][c]=1;
  664. if (direction==1) //If the lowest distance is north, move north
  665. p[r--][c]=1;
  666. if (direction==2) //If the lowest distance is east, move east
  667. p[r][c++]=1;
  668. if (direction==3) //If the lowest distance is west, move west
  669. p[r][c--]=1;
  670. }
  671. }
  672. }
  673.  
  674. boolean spaceLeft(int[][] m, int x) //Checks if the board has x or more spaces left
  675. {
  676. int emptySpaces = 0;
  677. boolean result = false;
  678. for (int i = 0; i < myRows; i++)
  679. for (int j = 0; j < myColumns; j++)
  680. if (m[i][j]==0)
  681. emptySpaces++;
  682. if (emptySpaces>x)
  683. result=true;
  684. return result;
  685. }
  686.  
  687. int cellsAmount(int[][] m, int x) //Obtains the number of cells with the value x on the matrix m
  688. {
  689. int result=0;
  690. for (int i = 0; i < myRows; i++)
  691. for (int j = 0; j < myColumns; j++)
  692. if (m[i][j]==x)
  693. result++;
  694. return result;
  695. }
  696.  
  697. int[] emptyCellsPositions() //Obtains the cell number of the empty cells
  698. {
  699. int[] result = new int[cellsAmount(board, 0)];
  700. int resulanimationTime=0;
  701. for (int i = 0; i < myRows; i++)
  702. for (int j = 0; j < myColumns; j++)
  703. if (board[i][j]==0)
  704. result[resulanimationTime++]=i*myColumns + j;
  705. return result;
  706. }
  707. // -----------------
  708. // Random Generators
  709. void ints_exchange(int[] a, int x, int y)
  710. {
  711. int m = a[x];
  712. a[x] = a[y];
  713. a[y] = m;
  714. }
  715.  
  716. void ints_shuffle(int[] a) //Knuth algoritm to shuffle arrays without duplicates
  717. {
  718. int n = a.length;
  719. for (int i = 0; i < n-1; i++)
  720. ints_exchange(a, i, i+int(random(n-1-i)));
  721. }
  722.  
  723. int[] randomEmptyCells(int n) //Returns n random empty cells numbers (positions)
  724. {
  725. int[] emptyCells = emptyCellsPositions();
  726. int[] rEmptyCells = new int[n];
  727. ints_shuffle(emptyCells); //Shuffles the emptyCells array (no duplicates)
  728. for (int i = 0; i < n; i++)
  729. rEmptyCells[i] = emptyCells[i];
  730. return rEmptyCells;
  731. }
  732.  
  733. int[] randomColors(int n) //Returns n random colors index (positions)
  734. {
  735. int[] rColors = new int [n];
  736. for (int i = 0; i < n; i++)
  737. {
  738. int rIndex = int(random(colors.length)+1); //we add 1 to the color index because, 0 means no color (empty cell), Note:Subtracted later in the myColors array, to obtain the position 0
  739. rColors[i] = rIndex;
  740. }
  741. return rColors;
  742. }
  743.  
  744. void fillRandom(int n) //Fill n cells, with n random colors
  745. {
  746. int[] rPositions = randomEmptyCells(n);
  747. int[] rColors = randomColors(n);
  748. int k=0;
  749. while (k<n)
  750. {
  751. for (int i = 0; i < myRows; i++)
  752. for (int j = 0; j < myColumns; j++)
  753. if (i*myColumns + j == rPositions[k])
  754. board[i][j] = rColors[k];
  755. k++;
  756. }
  757. }
  758.  
  759. void fillRandomBlocks(int n) //Fill n cells, with n random colors
  760. {
  761. int[] rPositions = randomEmptyCells(n);
  762. int k=0;
  763. while (k<n)
  764. {
  765. for (int i = 0; i < myRows; i++)
  766. for (int j = 0; j < myColumns; j++)
  767. if (i*myColumns + j == rPositions[k])
  768. board[i][j] = 404;
  769. k++;
  770. }
  771. }
  772. // -----------------
  773. // Cardinal Points (North, South, East, West)
  774. // Generate adjacent distances
  775. void S(int[][] m, int[][] d, int i, int j, int x) //SOUTH
  776. {
  777. if (i<myRows-1 && d[i+1][j]==-1 && m[i+1][j]==0) //If we are inside the matrix && the value is an empty position && the empty position does not have one ball
  778. d[i+1][j]=x+1;
  779. }
  780. void N(int[][] m, int[][] d, int i, int j, int x) //NORTH
  781. {
  782. if (i>0 && d[i-1][j]==-1 && m[i-1][j]==0)
  783. d[i-1][j]=x+1;
  784. }
  785. void E(int[][] m, int[][] d, int i, int j, int x) //EAST
  786. {
  787. if (j<myColumns-1 && d[i][j+1]==-1 && m[i][j+1]==0)
  788. d[i][j+1]=x+1;
  789. }
  790. void W(int[][] m, int[][] d, int i, int j, int x) //WEST
  791. {
  792. if (j>0 && d[i][j-1]==-1 && m[i][j-1]==0)
  793. d[i][j-1]=x+1;
  794. }
  795. // Adjacent distances
  796. void sDistance(int[][] d, int i, int j) //SOUTH
  797. {
  798. if (i<myRows-1) //If we are inside the matrix
  799. adjacent[0]=d[i+1][j];
  800. else
  801. adjacent[0]=9999; //Outside the matrix the distance is the "infinity"
  802. }
  803. void nDistance(int[][] d, int i, int j) //NORTH
  804. {
  805. if (i>0)
  806. adjacent[1]=d[i-1][j];
  807. else
  808. adjacent[1]=9999;
  809. }
  810. void eDistance(int[][] d, int i, int j) //EAST
  811. {
  812. if (j<myColumns-1)
  813. adjacent[2]=d[i][j+1];
  814. else
  815. adjacent[2]=9999;
  816. }
  817. void wDistance(int[][] d, int i, int j) //WEST
  818. {
  819. if (j>0)
  820. adjacent[3]=d[i][j-1];
  821. else
  822. adjacent[3]=9999;
  823. }
  824. // Adjacent path
  825. void sPath(int[][] m, int i, int j) //Checks if we have path to move SOUTH
  826. {
  827. if (i<myRows-1 && m[i+1][j]==1) //If we are inside the matrix && the value is an empty position && the empty position does not have one ball
  828. {
  829. board[i][j] = 0; //To create the animation, the cell behind must disappear
  830. m[i+1][j]=0; //We have no path in the current position
  831. temporaryCellY++; //Move south
  832. board[temporaryCellY][temporaryCellX] = previousCellColor;//Place a cell south
  833. } else
  834. nPath(path, temporaryCellY, temporaryCellX); //Can't move south try north
  835. }
  836. void nPath(int[][] m, int i, int j) //Checks if we have path to move NORTH
  837. {
  838. if (i>0 && m[i-1][j]==1)
  839. {
  840. board[i][j] = 0;
  841. m[i-1][j]=0;
  842. temporaryCellY--;
  843. board[temporaryCellY][temporaryCellX] = previousCellColor;
  844. } else
  845. ePath(path, temporaryCellY, temporaryCellX); //Can't move south try east
  846. }
  847. void ePath(int[][] m, int i, int j) //Checks if we have path to move EAST
  848. {
  849. if (j<myColumns-1 && m[i][j+1]==1)
  850. {
  851. board[i][j] = 0;
  852. m[i][j+1]=0;
  853. temporaryCellX++;
  854. board[temporaryCellY][temporaryCellX] = previousCellColor;
  855. } else
  856. wPath(path, temporaryCellY, temporaryCellX); //Can't move south try west
  857. }
  858. void wPath(int[][] m, int i, int j) //Checks if we have path to move WEST
  859. {
  860. if (j>0 && m[i][j-1]==1)
  861. {
  862. board[i][j] = 0;
  863. m[i][j-1]=0;
  864. temporaryCellX--;
  865. board[temporaryCellY][temporaryCellX] = previousCellColor;
  866. }
  867. }
  868. // -----------------
  869. // Mouse
  870. /*
  871. void keyPressed()
  872. {
  873. if (keyCode == BACKSPACE)
  874. {
  875. option1=false;
  876. end=false;
  877. selection=true;
  878. }
  879. }*/
  880. void mousePressed()
  881. {
  882. x = mouseX;
  883. y = mouseY;
  884. options();
  885.  
  886. if (x > marginWidth && x < myWidth-marginWidth && y > marginHeight && y < myHeight-marginHeight && !deleting && millis() >= t2 + pathSize*animationSpeed && option1) //Checks if the mouse is not clicking the margin && nothing needs to be deleted
  887. {
  888. t1 = millis(); //Mouse click time
  889. getCellAxis(x, y, cellWidth, cellHeight, marginWidth, marginHeight); //Gets cell coordinates
  890.  
  891. if (mouseClick && (distance[cellY][cellX] == 0 || board[cellY][cellX] == 404)) //If the second click is in the same ball, we get to choose another ball (Reset)
  892. {
  893. mouseClick = !mouseClick; //Go back to ball selection (1st click)
  894. matrixSetup(distance, -1); //Reset the distances, because a new ball has new distances
  895. } else if (mouseClick && distance[cellY][cellX] > 0) //Second click, delete last position, fill the new position and generate randoms
  896. {
  897. t2 = millis(); //2nd mouse click time
  898. shortestPath(distance, cellY, cellX, path); //Generate path
  899. pathSize = cellsAmount(path, 1); //Check the size of the path (to calculate animation time)
  900. delete = false; //We don't want to delete a sequence right after the click
  901. generateRandoms = true; //Permission to generate randoms (unless we have a sequence, has refered in line 87)
  902. matrixSetup(distance, -1); //Resets the distance matrix
  903. mouseClick = !mouseClick; //Switch to 1st click
  904. } else if (mouseClick && board[cellY][cellX] > 0 && board[cellY][cellX] != 404) //Second click, on another ball
  905. {
  906. matrixSetup(distance, -1); //Resets the distance matrix
  907. //gameplays from the beggining, but with the new ball
  908. distances(board, myRows, myColumns, cellY, cellX, distance);
  909. matrixSetup(path, 0);
  910. temporaryCellX = cellX;
  911. temporaryCellY = cellY;
  912. previousCellColor = board[cellY][cellX];
  913. }
  914. //First click, saves the position clicked, to use later on the second click
  915. else if (!mouseClick && board[cellY][cellX] > 0 && board[cellY][cellX] != 404) //The else if is used, so that the mousePressed function only activates one of the clicks
  916. {
  917. distances(board, myRows, myColumns, cellY, cellX, distance); //Generates the distances from the clicked cell
  918. matrixSetup(path, 0);
  919. temporaryCellX = cellX;
  920. temporaryCellY = cellY; //OPTIMIZE
  921. previousCellColor = board[cellY][cellX]; //OPTIMIZE
  922. mouseClick = !mouseClick; //Switch to 2nd click
  923. }
  924. }
  925. }
  926. // -----------------
  927. // Options menu
  928. void options()
  929. {
  930. if (start)
  931. {
  932. start=false;
  933. selection=true;
  934. }
  935.  
  936. else if(selection)
  937. {
  938. if (x > myWidth/4 - 75 && x < myWidth/4 + 75 && y > myHeight/3 - 75 && y < myHeight/3 + 75) //option1
  939. {
  940. gameSetup();
  941. selection=false;
  942. option1=true;
  943. t3=millis();
  944. }
  945. else if(x > (3*myWidth)/4 - 75 && x < (3*myWidth)/4 + 75 && y > myHeight/3 - 75 && y < myHeight/3 + 75) //option3
  946. {
  947. scanCountdown=millis();
  948. scanT1=millis();
  949. selection=false;
  950. option3=true;
  951. }
  952. else if (x > myWidth/4 - 75 && x < myWidth/4 + 75 && y > 2*myHeight/3 - 95 && y < 2*myHeight/3 + 55) //option4
  953. {
  954. selection=false;
  955. option4=true;
  956. }
  957. else if (x > myWidth/2 - 75 && x < myWidth/2 + 75 && y > 2*myHeight/3 - 95 && y < 2*myHeight/3 + 55) //option5
  958. {
  959. selection=false;
  960. option5=true;
  961. }
  962. else if (x > (3*myWidth)/4 - 75 && x < (3*myWidth)/4 + 75 && y > 2*myHeight/3 - 95 && y < 2*myHeight/3 + 55) //option6
  963. {
  964. selection=false;
  965. option6=true;
  966. }
  967. }
  968.  
  969. else if(option4)
  970. option4();
  971.  
  972. else if(option5)
  973. option5();
  974.  
  975. else if(option6)
  976. option6();
  977. }
  978.  
  979. void optionsMoved()
  980. {
  981. if(selection)
  982. {
  983. if (movedX > myWidth/4 - 75 && movedX < myWidth/4 + 75 && movedY > myHeight/3 - 75 && movedY < myHeight/3 + 75 && selection) //option1
  984. {
  985. boxSettings(false, 0, true, lawngreen, 6, 255);
  986. rect(myWidth/4, myHeight/3, 150, 150);
  987. }
  988. else if (movedX > myWidth/4 - 75 && movedX < myWidth/4 + 75 && movedY > 2*myHeight/3 - 95 && movedY < 2*myHeight/3 + 55) //option4
  989. {
  990. boxSettings(false, 0, true, blue, 6, 255);
  991. rect(myWidth/4, 2*myHeight/3 - 20, 150, 150);
  992. }
  993. else if (movedX > myWidth/2 - 75 && movedX < myWidth/2 + 75 && movedY > 2*myHeight/3 - 95 && y < 2*myHeight/3 + 55 && selection) //option5
  994. {
  995. boxSettings(false, 0, true, magenta, 6, 255);
  996. rect(myWidth/2, 2*myHeight/3 - 20, 150, 150);
  997. }
  998. else if (movedX > (3*myWidth)/4 - 75 && movedX < (3*myWidth)/4 + 75 && movedY > 2*myHeight/3 - 95 && movedY < 2*myHeight/3 + 55) //option6
  999. {
  1000. boxSettings(false, 0, true, yellow, 6, 255);
  1001. rect(3*myWidth/4, 2*myHeight/3 - 20, 150, 150);
  1002. }
  1003. }
  1004. else if(option4)
  1005. submenu();
  1006.  
  1007. else if(option5)
  1008. submenu();
  1009.  
  1010. else if(option6)
  1011. submenu();
  1012. }
  1013.  
  1014. void option2()
  1015. {
  1016. }
  1017. void option3()
  1018. {
  1019. }
  1020. void option4()
  1021. {
  1022. if (x > myWidth/4 - 75 && x < myWidth/4 + 75 && y > myHeight/2 - 75 && y < myHeight/2 + 75) //Option 4, 1st Box
  1023. {
  1024. println("4 - 1st Box");
  1025. option4=false;
  1026. selection=true;
  1027. myRows=16;
  1028. myColumns=20;
  1029. cellWidth = (myWidth - 2.0*marginWidth)/myColumns;
  1030. cellHeight = (myHeight - 2.0*marginHeight)/myRows;
  1031. if(medium)
  1032. blocks= int(myColumns*myRows * 0.10);
  1033. if(hard)
  1034. blocks= int(myColumns*myRows * 0.20);
  1035. boardSize="16x20";
  1036. }
  1037. else if (x > myWidth/2 - 75 && x < myWidth/2 + 75 && y > myHeight/2 - 75 && y < myHeight/2 + 75) //Option 4, 2nd Box
  1038. {
  1039. println("4 - 2nd Box");
  1040. option4=false;
  1041. selection=true;
  1042. myRows=8;
  1043. myColumns=10;
  1044. cellWidth = (myWidth - 2.0*marginWidth)/myColumns;
  1045. cellHeight = (myHeight - 2.0*marginHeight)/myRows;
  1046. if(medium)
  1047. blocks= int(myColumns*myRows * 0.10);
  1048. if(hard)
  1049. blocks= int(myColumns*myRows * 0.20);
  1050. boardSize="8x10";
  1051. }
  1052. else if (x > (3*myWidth)/4 - 75 && x < (3*myWidth)/4 + 75 && y > myHeight/2 - 75 && y < myHeight/2 + 75) //Option 4, 3rd Box
  1053. {
  1054. println("4 - 3rd Box");
  1055. option4=false;
  1056. selection=true;
  1057. myRows=4;
  1058. myColumns=5;
  1059. cellWidth = (myWidth - 2.0*marginWidth)/myColumns;
  1060. cellHeight = (myHeight - 2.0*marginHeight)/myRows;
  1061. if(medium)
  1062. blocks= int(myColumns*myRows * 0.10);
  1063. if(hard)
  1064. blocks= int(myColumns*myRows * 0.20);
  1065. boardSize="4x5";
  1066. }
  1067. }
  1068.  
  1069. void option5()
  1070. {
  1071. if (x > myWidth/4 - 75 && x < myWidth/4 + 75 && y > myHeight/2 - 75 && y < myHeight/2 + 75) //Option 5, 1st Box
  1072. {
  1073. println("5 - 1st Box");
  1074. option5=false;
  1075. selection=true;
  1076. colors=myColors3;
  1077. colorNumber="3 Colors";
  1078. }
  1079. else if (x > myWidth/2 - 75 && x < myWidth/2 + 75 && y > myHeight/2 - 75 && y < myHeight/2 + 75) //Option 5, 2nd Box
  1080. {
  1081. println("5 - 2nd Box");
  1082. option5=false;
  1083. selection=true;
  1084. colors=myColors6;
  1085. colorNumber="6 Colors";
  1086. }
  1087. else if (x > (3*myWidth)/4 - 75 && x < (3*myWidth)/4 + 75 && y > myHeight/2 - 75 && y < myHeight/2 + 75) //Option 5, 3rd Box
  1088. {
  1089. println("5 - 3rd Box");
  1090. option5=false;
  1091. selection=true;
  1092. colors=myColors9;
  1093. colorNumber="9 Colors";
  1094. }
  1095. }
  1096. void option6()
  1097. {
  1098. if (x > myWidth/4 - 75 && x < myWidth/4 + 75 && y > myHeight/2 - 75 && y < myHeight/2 + 75) //Option 6, 1st Box
  1099. {
  1100. println("6 - 1st Box");
  1101. option6=false;
  1102. selection=true;
  1103. blocks=0;
  1104. difficulty="Easy";
  1105. }
  1106. else if (x > myWidth/2 - 75 && x < myWidth/2 + 75 && y > myHeight/2 - 75 && y < myHeight/2 + 75) //Option 6, 2nd Box
  1107. {
  1108. println("6 - 2nd Box");
  1109. medium=true;
  1110. hard=false;
  1111. option6=false;
  1112. selection=true;
  1113. blocks = int(myColumns*myRows * 0.10); //10% of the blocks are locked
  1114. difficulty="Medium";
  1115. }
  1116. else if (x > (3*myWidth)/4 - 75 && x < (3*myWidth)/4 + 75 && y > myHeight/2 - 75 && y < myHeight/2 + 75) //Option 6, 3rd Box
  1117. {
  1118. println("6 - 3rd Box");
  1119. medium=false;
  1120. hard=true;
  1121. option6=false;
  1122. selection=true;
  1123. blocks = int(myColumns*myRows * 0.20);
  1124. difficulty="Hard";
  1125. }
  1126. }
  1127.  
  1128. void submenu()
  1129. {
  1130. if (x > myWidth/4 - 75 && x < myWidth/4 + 75 && y > myHeight/2 - 75 && y < myHeight/2 + 75) //Option 4, 1st Box
  1131. {
  1132. boxSettings(false, 0, true, lawngreen, 6, 255);
  1133. rect(myWidth/4, myHeight/2, 150, 150);
  1134. }
  1135. else if (x > myWidth/2 - 75 && x < myWidth/2 + 75 && y > myHeight/2 - 75 && y < myHeight/2 + 75) //Option 4, 2nd Box
  1136. {
  1137. boxSettings(false, 0, true, blue, 6, 255);
  1138. rect(myWidth/2, myHeight/2, 150, 150);
  1139. }
  1140. else if (x > (3*myWidth)/4 - 75 && x < (3*myWidth)/4 + 75 && y > myHeight/2 - 75 && y < myHeight/2 + 75) //Option 4, 3rd Box
  1141. {
  1142. boxSettings(false, 0, true, red, 6, 255);
  1143. rect(3*myWidth/4, myHeight/2, 150, 150);
  1144. }
  1145. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement