Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enabled Multiplayer Feature #2

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
60 changes: 43 additions & 17 deletions src/KeyboardListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,51 @@ public class KeyboardListener extends KeyAdapter{

public void keyPressed(KeyEvent e){
switch(e.getKeyCode()){
case 39: // -> Right
//if it's not the opposite direction
if(ThreadsController.directionSnake!=2)
ThreadsController.directionSnake=1;
break;
case 38: // -> Top
if(ThreadsController.directionSnake!=4)
ThreadsController.directionSnake=3;
break;

//Player One Controls
case 39: // -> Right
//if it's not the opposite direction
if(ThreadsController.directionSnake!=2)
ThreadsController.directionSnake=1;
break;
case 38: // -> Top
if(ThreadsController.directionSnake!=4)
ThreadsController.directionSnake=3;
break;

case 37: // -> Left
if(ThreadsController.directionSnake!=1)
ThreadsController.directionSnake=2;
break;
case 37: // -> Left
if(ThreadsController.directionSnake!=1)
ThreadsController.directionSnake=2;
break;

case 40: // -> Bottom
if(ThreadsController.directionSnake!=3)
ThreadsController.directionSnake=4;
break;
case 40: // -> Bottom
if(ThreadsController.directionSnake!=3)
ThreadsController.directionSnake=4;
break;

//Player Two Controls

case KeyEvent.VK_D: // -> Player 2 Right
if(ThreadsControllerPlayerTwo.directionSnake != 2)
ThreadsControllerPlayerTwo.directionSnake = 1;
break;


case KeyEvent.VK_W: // -> Player 2 Top
if(ThreadsControllerPlayerTwo.directionSnake != 4)
ThreadsControllerPlayerTwo.directionSnake = 3;
break;

case KeyEvent.VK_A: // -> Player 2 Left
if(ThreadsControllerPlayerTwo.directionSnake != 1)
ThreadsControllerPlayerTwo.directionSnake = 2;
break;


case KeyEvent.VK_S: // -> Player 2 Bottom
if(ThreadsControllerPlayerTwo.directionSnake != 3)
ThreadsControllerPlayerTwo.directionSnake = 4;
break;

default: break;
}
Expand Down
4 changes: 2 additions & 2 deletions src/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ public class Main {

public static void main(String[] args) {

//Creating the window with all its awesome snaky features
Window f1= new Window();
//Creating the window with all its awesome snakey features
Window f1 = new Window();

//Setting up the window settings
f1.setTitle("Snake");
Expand Down
2 changes: 1 addition & 1 deletion src/ThreadsController.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ private void checkCollision() {

//Stops The Game
private void stopTheGame(){
System.out.println("COLISION! \n");
System.out.println("COLLISION! \n");
while(true){
pauser();
}
Expand Down
169 changes: 169 additions & 0 deletions src/ThreadsControllerPlayerTwo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
import java.util.ArrayList;


//Controls all the game logic .. most important class in this project.
public class ThreadsControllerPlayerTwo extends Thread {
ArrayList<ArrayList<DataOfSquare>> Squares= new ArrayList<ArrayList<DataOfSquare>>();
Tuple headSnakePos;
int sizeSnake=3;
long speed = 50;
public static int directionSnake ;

ArrayList<Tuple> positions = new ArrayList<Tuple>();
Tuple foodPosition;

//Constructor of ControlleurThread
ThreadsControllerPlayerTwo(Tuple positionDepart){
//Get all the threads
Squares=Window.Grid;

headSnakePos=new Tuple(positionDepart.x,positionDepart.y);
directionSnake = 1;

//!!! Pointer !!!!
Tuple headPos = new Tuple(headSnakePos.getX(),headSnakePos.getY());
positions.add(headPos);

foodPosition= new Tuple(Window.height-1,Window.width-1);
spawnFood(foodPosition);

}

//Important part :
public void run() {
while(true){
moveInterne(directionSnake);
checkCollision();
moveExterne();
deleteTail();
pauser();
}
}

//delay between each move of the snake
private void pauser(){
try {
sleep(speed);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

//Checking if the snake bites itself or is eating
private void checkCollision() {
Tuple posCritique = positions.get(positions.size()-1);
for(int i = 0;i<=positions.size()-2;i++){
boolean biteItself = posCritique.getX()==positions.get(i).getX() && posCritique.getY()==positions.get(i).getY();
if(biteItself){
stopTheGame();
}
}

boolean eatingFood = posCritique.getX()==foodPosition.y && posCritique.getY()==foodPosition.x;
if(eatingFood){
System.out.println("Yummy!");
sizeSnake=sizeSnake+1;
foodPosition = getValAleaNotInSnake();

spawnFood(foodPosition);
}
}

//Stops The Game
private void stopTheGame(){
System.out.println("COLLISION! \n");
while(true){
pauser();
}
}

//Put food in a position and displays it
private void spawnFood(Tuple foodPositionIn){
Squares.get(foodPositionIn.x).get(foodPositionIn.y).lightMeUp(1);
}

//return a position not occupied by the snake
private Tuple getValAleaNotInSnake(){
Tuple p ;
int ranX= 0 + (int)(Math.random()*19);
int ranY= 0 + (int)(Math.random()*19);
p=new Tuple(ranX,ranY);
for(int i = 0;i<=positions.size()-1;i++){
if(p.getY()==positions.get(i).getX() && p.getX()==positions.get(i).getY()){
ranX= 0 + (int)(Math.random()*19);
ranY= 0 + (int)(Math.random()*19);
p=new Tuple(ranX,ranY);
i=0;
}
}
return p;
}

//Moves the head of the snake and refreshes the positions in the arraylist
//1:right 2:left 3:top 4:bottom 0:nothing
private void moveInterne(int dir){
switch(dir){
case 4:
headSnakePos.ChangeData(headSnakePos.x,(headSnakePos.y+1)%20);
positions.add(new Tuple(headSnakePos.x,headSnakePos.y));
break;
case 3:
if(headSnakePos.y-1<0){
headSnakePos.ChangeData(headSnakePos.x,19);
}
else{
headSnakePos.ChangeData(headSnakePos.x,Math.abs(headSnakePos.y-1)%20);
}
positions.add(new Tuple(headSnakePos.x,headSnakePos.y));
break;
case 2:
if(headSnakePos.x-1<0){
headSnakePos.ChangeData(19,headSnakePos.y);
}
else{
headSnakePos.ChangeData(Math.abs(headSnakePos.x-1)%20,headSnakePos.y);
}
positions.add(new Tuple(headSnakePos.x,headSnakePos.y));

break;
case 1:
headSnakePos.ChangeData(Math.abs(headSnakePos.x+1)%20,headSnakePos.y);
positions.add(new Tuple(headSnakePos.x,headSnakePos.y));
break;
}
}

//Refresh the squares that needs to be
private void moveExterne(){
for(Tuple t : positions){
int y = t.getX();
int x = t.getY();
Squares.get(x).get(y).lightMeUp(0);

}
}

//Refreshes the tail of the snake, by removing the superfluous data in positions arraylist
//and refreshing the display of the things that is removed
private void deleteTail(){
int cmpt = sizeSnake;
for(int i = positions.size()-1;i>=0;i--){
if(cmpt==0){
Tuple t = positions.get(i);
Squares.get(t.y).get(t.x).lightMeUp(2);
}
else{
cmpt--;
}
}
cmpt = sizeSnake;
for(int i = positions.size()-1;i>=0;i--){
if(cmpt==0){
positions.remove(i);
}
else{
cmpt--;
}
}
}
}
48 changes: 43 additions & 5 deletions src/Window.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.util.ArrayList;

import javax.swing.JFrame;
import javax.swing.JOptionPane;


class Window extends JFrame{
Expand Down Expand Up @@ -37,6 +38,33 @@ public Window(){
}
}



/*
* The below code makes a JOptionPane ask the user if he/she wants to play with
* one player or two player, and sets up the game accordingly.
*/

String[] options = {"One player" , "Two Players"};
int playersSelected = JOptionPane.showOptionDialog(null, "Would you like to play single player or multiplayer?",
"A Silly Question",
JOptionPane.YES_NO_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE,
null,
options,
options[1]);

//If user selects "Two Player"
if(playersSelected == 1){
//Set up Player Two Controller
Tuple position2 = new Tuple(13,13);
ThreadsControllerPlayerTwo c2 = new ThreadsControllerPlayerTwo(position2);
c2.start();
}

//If User selects "One Player" or exits out of JOptionPane, game starts with only one player


// initial position of the snake
Tuple position = new Tuple(10,10);
// passing this value to the controller
Expand All @@ -46,12 +74,22 @@ public Window(){

// Links the window to the keyboardlistenner.
this.addKeyListener((KeyListener) new KeyboardListener());

//To do : handle multiplayers .. The above works, test it and see what happens

//Tuple position2 = new Tuple(13,13);
//ControlleurThreads c2 = new ControlleurThreads(position2);
//c2.start();

/*TODO:
* Problems With Multiplayer:
* -When one player eats food, and then the other player eats food, the food completely disappears.
* -The two players can freely go through each other (no collision happens between two players).
* This does not necessarily need to be fixed, but it would be interesting to allow
* players to make other players collide in order to win (like original snake of light cycle games).
* This feature would also give more motivation to get the food (the more food you get,
* the longer you are, the more of a chance you have of trapping opponent).
*
* If this feature is not implemented, an alternative would be to show a "scoreboard" on the
* right of the screen, and set a time limit to see which player can get most food
* (without colliding into itself).
*/


}
}