MichaelSinn_

Caterpillar Lunch Code

Sep 28th, 2020
211
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. let dataServer;
  2. let pubKey = 'pub-c-78d9ee8d-b27d-463a-a05d-528b91cb6a56';
  3. let subKey = 'sub-c-7dcb509c-f6af-11ea-a5ac-ca9fd24ed40e';
  4. let background;
  5.  
  6. // Define global variables
  7. // SPR Header means image
  8. let spr_raspberry;
  9. let spr_leaf;
  10. let spr_enemy_head;
  11. let spr_enemy_body;
  12. let spr_local_head;
  13. let spr_local_body;
  14.  
  15. let spr_gameover;
  16. let spr_snail_d;
  17. let spr_snail_r;
  18. let spr_ant_u;
  19. let spr_ant_d;
  20. let spr_ant_r;
  21. let spr_ant_l;
  22.  
  23. let spr_won;
  24. let bite1;
  25. let bite2;
  26. let death;
  27.  
  28. // Lists for the various items and animals in the game as NPCs
  29. let ants = [];
  30. let items = [];
  31. let snails = [];
  32. let dir = undefined;
  33.  
  34. // Generate a unique UUID
  35. let UUID = PubNub.generateUUID();
  36.  
  37. let dataToSend = {
  38. player: undefined,
  39. req: undefined
  40. }
  41.  
  42. let dataReceived = [];
  43. let oPlayer = undefined;
  44.  
  45. let channelName = "game";
  46. let cell_size = 32;
  47.  
  48. // Define canvas size
  49. let game_width = 700;
  50. let game_height = 700;
  51.  
  52. class Item{ // Item class (What the caterpillar eats)
  53. constructor() {
  54. this.type = Math.floor(Math.random() * 4); // Determine if the image will be a leaf or a raspberry
  55. this.x = Math.floor(Math.random() * game_width/cell_size) * cell_size - 8; // Spawn at random place
  56. this.y = Math.floor(Math.random() * game_height/cell_size) * cell_size - 8;
  57. };
  58. }
  59.  
  60. class Mob{ // Mob parent class (Snails and Ants)
  61. constructor() {
  62. // Spawn at random point
  63. this.x = Math.floor(Math.random() * game_width/cell_size);
  64. this.y = Math.floor(Math.random() * game_height/cell_size);
  65.  
  66. // Spawn off screen and set beginning direction
  67. if(this.x > this.y){
  68. this.y = 0;
  69. this.dir = 1;
  70. }else{
  71. this.x = 0;
  72. this.dir = 3;
  73. }
  74. }
  75. }
  76.  
  77. class Snail extends Mob{ // Snail class
  78. constructor() {
  79. super(); // Inherit the parent class constructor
  80. }
  81. move(){ // Used to move the snail in a constant direction at 0.5 the speed of the player
  82. if (this.dir === 1){
  83. this.y += 0.5;
  84. }else if (this.dir === 3){
  85. this.x += 0.5;
  86. }
  87. }
  88. }
  89.  
  90. class Ants extends Mob{ // Ant class
  91. constructor() {
  92. super(); // Inherit the parent class constructor
  93. this.spaces_moved = 0; // Used to determine whether the ant will change direction
  94. // Move to the opposite side of the screen to start
  95. if (this.x === 0){
  96. this.x = game_width / cell_size;
  97. this.dir = 2;
  98. }else if(this.y === 0){
  99. this.y = game_height / cell_size;
  100. this.dir = 1;
  101. }
  102. // Determine how many ants in the line
  103. this.size = Math.floor(Math.random() * 7) + 6;
  104. this.pos = [];
  105. this.pos_dir = [];
  106. // Generate the list of positions for the ants and the direction they're facing
  107. for (let i = 0; i < this.size; i++){
  108. if (this.dir === 3) {
  109. this.pos.push([this.x + i, this.y]);
  110. }else{
  111. this.pos.push([this.x, this.y + i]);
  112. }
  113. this.pos_dir.push(this.dir);
  114. }
  115. }
  116.  
  117. move(){ // Move the ants
  118. let old_dir;
  119. // If you've moved more than 6 spaces, you can now change your direction
  120. if(this.spaces_moved > 6){
  121. if(Math.floor(Math.random() * 3) === 2){ // 1/3 chance to change direction
  122. old_dir = this.dir;
  123. while(true) { // Check that they didn't double back on themselves
  124. this.dir = Math.floor(Math.random() * 4);
  125. if(old_dir !== 1 && this.dir === 0){
  126. // W
  127. this.dir = 0;
  128. break;
  129. }
  130. else if(old_dir !== 0 && this.dir === 1){
  131. // S
  132. this.dir = 1;
  133. break;
  134. }
  135. else if(old_dir !== 3 && this.dir === 2){
  136. // A
  137. this.dir = 2;
  138. break;
  139. }
  140. else if(old_dir !== 2 && this.dir === 3){
  141. // D
  142. this.dir = 3;
  143. break;
  144. }
  145. }
  146. this.spaces_moved = 0; // Need to move 6 more spaces because the direction has been changed
  147. }
  148. }
  149. // Move the last ant to the beginning of the line to give the impression that the ants are moving in a line
  150. this.pos[this.pos.length - 1][0] = this.pos[0][0];
  151. this.pos[this.pos.length - 1][1] = this.pos[0][1];
  152. switch (this.dir){
  153. case 0:
  154. // UP
  155. this.pos[this.pos.length - 1][1] -= 1;
  156. break;
  157. case 1:
  158. // DOWN
  159. this.pos[this.pos.length - 1][1] += 1;
  160. break;
  161. case 2:
  162. // LEFT
  163. this.pos[this.pos.length -1][0] -= 1;
  164. break;
  165. case 3:
  166. // RIGHT
  167. this.pos[this.pos.length - 1][0] += 1;
  168. break;
  169. case undefined:
  170. return;
  171. }
  172. // Change the ants positions
  173. this.pos_dir[this.pos_dir.length - 1] = this.dir;
  174. let holder2 = this.pos_dir[this.pos_dir.length - 1];
  175. this.pos_dir.pop();
  176. this.pos_dir.unshift(holder2);
  177. let holder = this.pos[this.pos.length -1];
  178. this.pos.pop();
  179. this.pos.unshift(holder);
  180. this.spaces_moved ++;
  181. }
  182. }
  183.  
  184. function setup() // Initialize the game
  185. {
  186. // Load in all of the images and sounds
  187. spr_leaf = loadImage("Assets/Images/leaf.png");
  188. spr_raspberry = loadImage("Assets/Images/raspberry.png");
  189. background = loadImage("Assets/Images/bg.png");
  190.  
  191. spr_local_body = loadImage("Assets/Images/l_body1.png");
  192. spr_gameover = loadImage("Assets/Images/gameover.png");
  193.  
  194. spr_local_head = loadImage("Assets/Images/l_head.png");
  195.  
  196. spr_enemy_body = loadImage("Assets/Images/e_body.png");
  197. spr_enemy_head = loadImage("Assets/Images/e_head.png");
  198. spr_won = loadImage("Assets/Images/youwon.png");
  199.  
  200. spr_ant_u = loadImage("Assets/Images/ant.png");
  201. spr_ant_d = loadImage("Assets/Images/ant_d.png");
  202. spr_ant_r = loadImage("Assets/Images/ant_r.png");
  203. spr_ant_l = loadImage("Assets/Images/ant_l.png");
  204.  
  205. spr_snail_d = loadImage("Assets/Images/snail_d.png");
  206. spr_snail_r = loadImage("Assets/Images/snail_r.png");
  207.  
  208. background_song = new Audio("Assets/Sounds/FrenchToast.wav");
  209. bite1 = new Audio("Assets/Sounds/Bite1.wav");
  210. bite2 = new Audio("Assets/Sounds/GrapeBite.wav");
  211. death = new Audio("Assets/Sounds/DyingSound.wav");
  212.  
  213. // Set the framerate for the game and initialize the canvas
  214. frameRate(7);
  215. createCanvas(game_width, game_height);
  216.  
  217. // Player object
  218. local_player = {
  219. won: undefined,
  220. steps: 0,
  221. colour: color(0, 255, 0),
  222. pos: [[5, 5], [4, 5], [3, 5]],
  223. id: UUID,
  224. dir: undefined
  225. };
  226.  
  227. // Connect to the PubNub Server
  228. dataServer = new PubNub({
  229. publish_key : pubKey,
  230. subscribe_key : subKey,
  231. ssl: true,
  232. uuid: UUID
  233. });
  234.  
  235. dataServer.addListener({ message: readIncoming });
  236. dataServer.subscribe({channels: [channelName]});
  237. sendTheMessage(local_player, true);
  238. ant = new Ants();
  239. }
  240.  
  241. function move(p){ // Move the player
  242. // Same general code as the ants except it doesn't change the direction of each individual piece so is much simpler
  243. positions = p.pos;
  244. // Move the back of the player to the front
  245. positions[positions.length - 1][0] = positions[0][0];
  246. positions[positions.length - 1][1] = positions[0][1];
  247. switch (p.dir){ // Move based on the direction
  248. case 0:
  249. // UP
  250. positions[positions.length - 1][1] -= 1;
  251. break;
  252. case 1:
  253. // DOWN
  254. positions[positions.length - 1][1] += 1;
  255. break;
  256. case 2:
  257. // LEFT
  258. positions[positions.length -1][0] -= 1;
  259. break;
  260. case 3:
  261. // RIGHT
  262. positions[positions.length - 1][0] += 1;
  263. break;
  264. case undefined:
  265. return;
  266. }
  267. // Swap the position of the last index to the beginning and shift everything down one
  268. holder = positions[positions.length -1];
  269. positions.pop();
  270. positions.unshift(holder);
  271. p.pos = positions;
  272. }
  273.  
  274. function spawn_item(){ // Spawns a new item for the players to eat
  275. nItem = new Item();
  276. items.push(nItem);
  277. sendTheMessage(local_player, false); // Sends the item to the other player
  278. }
  279.  
  280. function collision(p1, p2){ // Checks for collisions between the two players, the player and the snails, ants and edge of screen
  281. switch (p1.dir){ // Gets the position of the next move
  282. case 0:
  283. // UP
  284. d = -1;
  285. r = 0;
  286. break;
  287. case 1:
  288. // DOWN
  289. d = 1;
  290. r = 0;
  291. break;
  292. case 2:
  293. // LEFT
  294. r = -1;
  295. d = 0;
  296. break;
  297. case 3:
  298. // RIGHT
  299. r = 1
  300. d = 0;
  301. break;
  302. case undefined:
  303. r = 0;
  304. d = 0;
  305. }
  306.  
  307. // If the other player has been loaded in, check if your head has hit them
  308. if(p2 !== undefined) {
  309. for (let i = 0; i < p2.pos.length; i++) {
  310. if ((p1.pos[0][0] + r === p2.pos[i][0]) && (p1.pos[0][1] + d === p2.pos[i][1])) {
  311. return true;
  312. }
  313. }
  314. }
  315.  
  316. // Check for each snail to see if you hit them
  317. for(i =0; i < snails.length; i++) {
  318. if (p1.pos[0][0] + r === Math.floor(snails[i].x) && p1.pos[0][1] + d === Math.floor(snails[i].y)){
  319. return true;
  320. }
  321. }
  322.  
  323. // Check for each ant to see if you hit them
  324. for(e=0; e < ants.length; e++){
  325. for(i = 0; i < ants[e].pos.length; i++){
  326. if(p1.pos[0][0] + r === Math.floor(ants[e].pos[i][0]) && p1.pos[0][1] + d === Math.floor(ants[e].pos[i][1])){
  327. return true;
  328. }
  329. }
  330. }
  331. // Check if you're off screen. If all are false you did not hit anything.
  332. return p1.pos[0][0] + r > game_width / cell_size + 1 || p1.pos[0][0] + r < -1 || p1.pos[0][1] + d > game_height / cell_size + 1 || p1.pos[0][1] < 0;
  333. }
  334.  
  335. function checkWon(p){
  336. // Checks if you have won by reaching a length of 20, and if not then checks how 'hungry' you are and removes length from you if
  337. // You're too hungry
  338. if (p.pos.length > 15){
  339. p.won = true;
  340. }
  341. if(p.pos.length <= 1){
  342. local_player.won = false;
  343. }
  344. if(p.steps > 20){
  345. p.pos.pop();
  346. p.steps = 0;
  347. }
  348. }
  349.  
  350. function draw() { // Main function
  351. // 1 in 40 chance to spawn a new snail
  352. if(Math.floor(Math.random()*40) === 2){
  353. snails.push(new Snail());
  354. }
  355. // 1 in 60 chance to spawn a new ant
  356. if(Math.floor(Math.random()*60) === 2){
  357. ants.push(new Ants());
  358. }
  359. // Draw the background
  360. image(background,0,0,700,700);
  361.  
  362. // Draw each snail depending on their direction
  363. for (i = 0; i < snails.length; i++){
  364. if(snails[i].dir === 1){
  365. image(spr_snail_d, snails[i].x * cell_size, snails[i].y * cell_size, 48, 48);
  366. }else{
  367. image(spr_snail_r, snails[i].x * cell_size, snails[i].y * cell_size, 48, 48);
  368. }
  369. // Move the snails
  370. snails[i].move();
  371. }
  372. // Draw each segment of the ant line depending on the direction that they are facing and moving in
  373. for (e = 0; e < ants.length; e++) {
  374. ants[e].move(); // Move the ants
  375. for (i = 0; i < ants[e].size; i++) {
  376. switch (ants[e].pos_dir[i]){
  377. case 0:
  378. image(spr_ant_u, ants[e].pos[i][0] * cell_size, ants[e].pos[i][1] * cell_size, cell_size, cell_size);
  379. break;
  380. case 1:
  381. image(spr_ant_d, ants[e].pos[i][0] * cell_size, ants[e].pos[i][1] * cell_size, cell_size, cell_size);
  382. break;
  383. case 2:
  384. image(spr_ant_l, ants[e].pos[i][0] * cell_size, ants[e].pos[i][1] * cell_size, cell_size, cell_size);
  385. break;
  386. case 3:
  387. image(spr_ant_r, ants[e].pos[i][0] * cell_size, ants[e].pos[i][1] * cell_size, cell_size, cell_size);
  388. break;
  389. }
  390. }
  391. }
  392.  
  393. // Play the background music
  394. if(!(background_song.duration > 0 && !background_song.paused)){
  395. background_song.play();
  396. }
  397.  
  398. checkWon(local_player); // Check if the player has won, or if they need to be shortened
  399. local_player.steps ++; // Increase number of spaces walked
  400.  
  401. // Draw each of the items and check if the player has eaten them
  402. if(items.length > 0) {
  403. if(items[0].type === 0){
  404. image(spr_raspberry, items[0].x, items[0].y, cell_size*1.5, cell_size*1.5);
  405. }else{
  406. image(spr_leaf, items[0].x, items[0].y, cell_size*1.5, cell_size*1.5);
  407. }
  408. switch (local_player.dir){
  409. case 0:
  410. // UP
  411. d = -1;
  412. r = 0;
  413. break;
  414. case 1:
  415. // DOWN
  416. d = 1;
  417. r = 0;
  418. break;
  419. case 2:
  420. // LEFT
  421. r = -1;
  422. d = 0;
  423. break;
  424. case 3:
  425. // RIGHT
  426. r = 1
  427. d = 0;
  428. break;
  429. case undefined:
  430. r = 0;
  431. d = 0;
  432. }
  433.  
  434. if ((local_player.pos[0][0] + r === (items[0].x + 8) / cell_size) && (local_player.pos[0][1] + d === (items[0].y + 8) / cell_size)) {
  435. // If the player has eaten the item, the player gains one length at the point the item was, steps and reset and a new item is spawned
  436. local_player.pos.push([local_player.pos[0][0] + r, local_player.pos[0][1] + d, Math.floor(Math.random()*4)]);
  437. local_player.steps = 0;
  438. if(items[0].type === 0){
  439. //Berry
  440. bite1.play();
  441. }else{
  442. // Leaf
  443. bite2.play();
  444. }
  445. items.shift();
  446. spawn_item();
  447. }
  448. }else{
  449. spawn_item(); // If there are no items, spawn one
  450. }
  451.  
  452. // Local player
  453.  
  454. // Move the local player
  455. move(local_player);
  456. image(spr_local_head, local_player.pos[0][0] * cell_size - 8, local_player.pos[0][1] * cell_size - 8, cell_size*1.5, cell_size*1.5); // Draw the player head
  457. // Draw the player body
  458. for (i = 1; i < local_player.pos.length; i ++){
  459. image(spr_local_body, local_player.pos[i][0] * cell_size - 8, local_player.pos[i][1] * cell_size - 8, cell_size*1.5, cell_size*1.5);
  460. }
  461.  
  462. // Check for collisions, if there is one you have lost.
  463. if (collision(local_player, oPlayer) && local_player.dir !== undefined) {
  464. local_player.won = false;
  465. }
  466.  
  467. if(local_player.won == false){
  468. image(spr_gameover, 0, 0, 700, 700);
  469. sendTheMessage(local_player, false); // Tell the opponent they have won
  470. background_song.pause();
  471. death.play();
  472. noLoop(); // Stop the game
  473. }
  474.  
  475. // Other player
  476. if (dataReceived[0] !== undefined) {
  477. // Update the player from information received from the other client
  478. oPlayer = dataReceived[0].message.dataToSend.player;
  479.  
  480. move(oPlayer); // Move the other player locally to reduce messages sent
  481. // Draw the other players head
  482. image(spr_enemy_head, oPlayer.pos[0][0] * cell_size - 8, oPlayer.pos[0][1] * cell_size - 8, cell_size*1.5, cell_size*1.5);
  483. for (let i = 1; i < oPlayer.pos.length; i++) {
  484. // Draw the other players body
  485. image(spr_enemy_body, oPlayer.pos[i][0] * cell_size - 8, oPlayer.pos[i][1] * cell_size - 8, cell_size*1.5, cell_size*1.5);
  486. }
  487. }
  488.  
  489. // If you have won, stop the game and draw the win screen
  490. if(local_player.won === true){
  491. image(spr_won, 0, 0, 700, 700);
  492. noLoop();
  493. }
  494. }
  495.  
  496. function sendTheMessage(player, r) { // Sends information to the opponent
  497. dataToSend.player = player; // Local player object
  498. dataToSend.req = r; // Whether or not to request the opponent to send information back to you
  499. if(items.length > 0) {
  500. dataToSend.item = items[0]; // Items to send
  501. }
  502.  
  503. dataServer.publish(
  504. {
  505. channel: channelName,
  506. message:
  507. {
  508. dataToSend
  509. }
  510. });
  511. }
  512.  
  513. function readIncoming(inMessage) { // Read the messages sent to you from the opponent
  514. console.log(inMessage);
  515. if (inMessage.message.dataToSend.player.id === UUID){ // If it is a message from yourself, ignore it
  516. return
  517. }
  518.  
  519. if (inMessage.message.dataToSend.req === true) { // If the other player wants your information, send it
  520. sendTheMessage(local_player, false);
  521. }
  522.  
  523. exists = false; // check if the player that connected is already in the game
  524.  
  525. for (i = 0; i < dataReceived.length; i++) {
  526. if (inMessage.message.dataToSend.player.id === dataReceived[i].message.dataToSend.player.id) {
  527. dataReceived[i] = inMessage; // Overwrite the current player information with the new information
  528. exists = true
  529. }
  530. }
  531.  
  532. if (!exists){
  533. dataReceived.push(inMessage); // Makes sure not to overwrite the current player with the new player connection
  534. }
  535.  
  536. if(inMessage.message.dataToSend.player.won === false){
  537. local_player.won = true; // If the other player has lost, you have won
  538. }
  539. items[0] = inMessage.message.dataToSend.item; // Update the current item on the screen if the other player has eaten it
  540. console.log(dataReceived); // Log the data received
  541. }
  542.  
  543. function keyPressed() { // Used for movement
  544. if(keyCode === 87 && dir !== 1){
  545. // W
  546. dir = 0;
  547. }
  548. else if(keyCode === 83 && dir !== 0){
  549. // S
  550. dir = 1;
  551. }
  552. else if(keyCode === 65 && dir !== 3){
  553. // A
  554. dir = 2;
  555. }
  556. else if(keyCode === 68 && dir !== 2){
  557. // D
  558. dir = 3;
  559. }
  560. local_player.dir = dir; // Change the players direction
  561. sendTheMessage(local_player, false); // Update the other player that you have changed direction
  562. }
  563.  
  564.  
  565.  
RAW Paste Data