From 6d0772efe8bf447b80485f6a60b3a8464851ce5b Mon Sep 17 00:00:00 2001 From: Jean Luo <luoj3@mcmaster.ca> Date: Thu, 3 Nov 2016 09:07:10 -0400 Subject: [PATCH] mvc developed --- Game_Code/src/Game.java | 4 +- src/model/Ball.java | 37 +++++ src/model/GameModel.java | 38 +++++ src/model/Paddle.java | 47 ++++++ src/model/Player.java | 51 +++++++ src/startGame/GameController.java | 245 ++++++++++++++++++++++++++++++ src/startGame/PongGame.java | 20 +++ src/view/GameView.java | 68 +++++++++ src/view/Mode.java | 57 +++++++ src/view/Pong.java | 12 ++ src/view/PongGameDisplay.java | 119 +++++++++++++++ src/view/Tutorial.java | 8 + src/view/Welcome.java | 60 ++++++++ 13 files changed, 764 insertions(+), 2 deletions(-) create mode 100644 src/model/Ball.java create mode 100644 src/model/GameModel.java create mode 100644 src/model/Paddle.java create mode 100644 src/model/Player.java create mode 100644 src/startGame/GameController.java create mode 100644 src/startGame/PongGame.java create mode 100644 src/view/GameView.java create mode 100644 src/view/Mode.java create mode 100644 src/view/Pong.java create mode 100644 src/view/PongGameDisplay.java create mode 100644 src/view/Tutorial.java create mode 100644 src/view/Welcome.java diff --git a/Game_Code/src/Game.java b/Game_Code/src/Game.java index 2845be4..77ea340 100644 --- a/Game_Code/src/Game.java +++ b/Game_Code/src/Game.java @@ -12,7 +12,7 @@ import javax.swing.*; public class Game extends JPanel implements KeyListener, ActionListener { private int height, width; // the height and width of the screen - private Timer t = new Timer(1, this); // the 't' variable makes sure that there is a initial delay before the same starts off + private Timer t = new Timer(5, this); // the 't' variable makes sure that there is a initial delay before the same starts off private boolean first; //game state (starting/playing) private HashSet<String> keys = new HashSet<String>(); @@ -21,7 +21,7 @@ public class Game extends JPanel implements KeyListener, ActionListener { private final int SPEED = 1; //the speed of the paddles private int padH = 10, padW = 40; // paddle width/height private int bottomPadX, topPadX; // these represent the top and the bottom paddles in the game - private int inset = 10; // this helps determine the distance between the paddle + private int inset = 30; // this helps determine the distance between the paddle // - and the top and bottom screen boundaries // ball diff --git a/src/model/Ball.java b/src/model/Ball.java new file mode 100644 index 0000000..6ce1d0c --- /dev/null +++ b/src/model/Ball.java @@ -0,0 +1,37 @@ +package model; + +public class Ball { + + private int positionX; + private int positionY; + private final int SIZE = 20; + + //TODO + private int speed; + + public Ball(int x, int y){ + positionX = x; + positionY = y; + } + + public void setPositionX(int x){ + positionX = x; + } + + public void setPositionY(int y){ + positionY = y; + } + + public int getPositionX(){ + return positionX; + } + + public int getPositionY(){ + return positionY; + } + + public int getSize(){ + return SIZE; + } + +} diff --git a/src/model/GameModel.java b/src/model/GameModel.java new file mode 100644 index 0000000..b59dda0 --- /dev/null +++ b/src/model/GameModel.java @@ -0,0 +1,38 @@ +package model; + +public class GameModel { + + private Ball b1; + private Paddle p_player, p_computer; + private Player player, computer; + + public GameModel(int ballX, int ballY, int playerX, int playerY, int compX, int compY){ + b1 = new Ball(ballX, ballY); + p_player = new Paddle(playerX, playerY); + p_computer = new Paddle(compX, compY); + + //TODO + player = new Player(); + computer = new Player(); + } + + public Ball getBall(){ + return b1; + } + + public Paddle getPlayerPaddle(){ + return p_player; + } + + public Paddle getComputerPaddle(){ + return p_computer; + } + + public Player getPlayer(){ + return player; + } + + public Player getComputer(){ + return computer; + } +} diff --git a/src/model/Paddle.java b/src/model/Paddle.java new file mode 100644 index 0000000..738086e --- /dev/null +++ b/src/model/Paddle.java @@ -0,0 +1,47 @@ +package model; + +public class Paddle { + + private int positionX; + private int positionY; + + private final int HEIGHT = 10; + private final int WIDTH = 40; + private final int INSET = 10; + + //TODO + private int speed; + + public Paddle(int x, int y){ + positionX = x; + positionY = y; + } + + public void setPositionX(int x){ + positionX = x; + } + + public void setPositionY(int y){ + positionY = y; + } + + public int getPositionX(){ + return positionX; + } + + public int getPositionY(){ + return positionY; + } + + public int getWidth(){ + return WIDTH; + } + + public int getSize(){ + return HEIGHT; + } + + public int getInset(){ + return INSET; + } +} diff --git a/src/model/Player.java b/src/model/Player.java new file mode 100644 index 0000000..9a77426 --- /dev/null +++ b/src/model/Player.java @@ -0,0 +1,51 @@ +package model; + +public class Player { + + // Constant declaration for number of life + private final int LIFE = 3; + private final int NOLIFE = 0; + + // Variable declaration for storing the player score + private int score; + + /** + * Constructor for the player - set the score to be 0 initially + */ + public Player(){ + score = LIFE; + //TODO: POSITION X, POSITION Y + + } + + /** + * Decrease number of life of the player + */ + public void decrementLife(){ + score--; + } + + /** + * Increase score for a player + */ + public void incrementScore(){ + score++; + } + + /** + * Get the score of a player + * @return playerScore - return the score of the player + */ + public int getScore(){ + return score; + } + + /** + * Check whether the player loses the game or not + * @return - boolean indicating losing or not + */ + public boolean checkLoss(){ + if(score==NOLIFE){ return true;} + else{ return false; } + } +} diff --git a/src/startGame/GameController.java b/src/startGame/GameController.java new file mode 100644 index 0000000..9c58b97 --- /dev/null +++ b/src/startGame/GameController.java @@ -0,0 +1,245 @@ +package startGame; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.util.HashSet; + +import javax.swing.JFrame; +import javax.swing.Timer; + +import model.*; +import view.*; + +public class GameController{ + + private GameView v; + private GameModel m; + private Welcome w; + private Mode mode; + + private HashSet<String> keys = new HashSet<String>(); + + private JFrame gameFrame; + private int frameWidth, frameHeight; + private PongGameDisplay gameDisplay; + + private int velX=1, velY=1; + private int padWidth = 80, padHeight = 10; + private int bottomPadX, topPadX; + private int ballX, ballY, ballSize=20; + private int scoreTop, scoreBottom; + private int inset; + + private Timer t; + + public GameController(GameView v, GameModel m){ + this.v = v; + this.m = m; + + w = this.v.getWelcome(); + w.addListener(new WelcomepageListener()); + + mode = this.v.getmode(); + mode.addListener(new ModeListener()); + + //game = this.v.getGame(); + //game.addListener(new GameListener()); + + gameFrame = this.v.getGameFrame(); + gameDisplay = this.v.getGame(); + //gameDisplay.addListener(new GameListener()); + gameDisplay.addKeyListener(new GameListener()); + gameDisplay.setFocusable(true); + gameDisplay.setFocusTraversalKeysEnabled(false); + + } + + class WelcomepageListener implements ActionListener{ + + @Override + public void actionPerformed(ActionEvent e) { + // TODO Auto-generated method stub + Object source = e.getSource(); + + if(source==w.getStart()){ + mode.setVisible(true); + w.setVisible(false); + + } +// else if() + + } + + } + + class ModeListener implements ActionListener{ + + + @Override + public void actionPerformed(ActionEvent e) { + // TODO Auto-generated method stub + Object source = e.getSource(); + + if(source == mode.getSingle()){ + mode.setVisible(false); + gameFrame.setVisible(true); + + } + } + + } + + class GameListener implements ActionListener, KeyListener{ + + GameListener(){ + bottomPadX = gameDisplay.getBottom(); + frameWidth = v.getFrameWidth(); + frameHeight = v.getFrameHeight(); + + t = new Timer(5,this); + t.setInitialDelay(1000); // sets initial delay for the movement of the ball + t.start(); + + } + + @Override + public void actionPerformed(ActionEvent e) { + + // X-direction + if(ballX< 0 || ballX > frameWidth-ballSize){ + velX = -velX; + } + + // Y-direction + if(ballY < 0){ +System.out.println("touch top border"); + velY = -velY; + ++scoreBottom; + } else if(ballY+ballSize>frameHeight){ +System.out.println("touch bottom border"); + velY = -velY; + ++scoreTop; + } else if(ballY+ballSize>frameHeight-inset-padHeight && velY > 0 && ballX + ballSize >= bottomPadX && ballX <= bottomPadX + padWidth){ +System.out.println("touch bottom pad"); + velY = -velY; + } else if(ballY+ballSize<=ballSize+inset+padHeight && velY < 0 && ballX + ballSize >= topPadX && ballX <= topPadX + padWidth){ +System.out.println("touch top pad"); + velY = -velY; + } + +/* + // side walls + if (ballX < 0 || ballX > frameWidth - ballSize) { // making sure ball is horizontally within the frame (left&right) + velX = -velX; // reverse the ball position if trying to go out + } + // top / down walls + if (ballY < 0) { // similarly, for vertical position + velY = -velY; // reverse the ball position vertically + ++ scoreBottom; + System.out.println("bottom: "+scoreBottom); + gameDisplay.setBottomScore(scoreBottom); + } + + if (ballY + ballSize > frameHeight - ballSize) { // similarly, for the vertical position of bottom paddle + velY = -velY; + ++ scoreTop; // points are incremented if the paddle is missed by opponent +System.out.println("top: "+scoreTop); + gameDisplay.setTopScore(scoreTop); + } + // bottom pad + if (ballY + ballSize>= frameHeight - padHeight - inset && velY > 0) // similar to the previous parts + if (ballX + ballSize >= bottomPadX && ballX <= bottomPadX + padWidth) + velY = -velY; + + // top pad + if (ballY <= padHeight + inset && velY < 0) + if (ballX + ballSize >= topPadX && ballX <= topPadX + padWidth) + velY = -velY; +*/ + ballX += velX; + ballY += velY; + + gameDisplay.setBall(ballX,ballY); + + + // pressed keys + if (keys.size() == 1) { + if (keys.contains("LEFT")) { // left key is pressed + if(bottomPadX>0) { + //TODO: SPEED + bottomPadX-=3; + gameDisplay.setBottom(bottomPadX); + } + } + else if (keys.contains("RIGHT")) { // right key is pressed + if(bottomPadX < frameWidth - padWidth){ + //TODO: SPEED + bottomPadX+=3; + gameDisplay.setBottom(bottomPadX); + } + } + } + + // AI + double delta = ballX - topPadX; + if (delta > 0) { + + if(topPadX < frameWidth - padWidth){ + topPadX +=1; + gameDisplay.setTop(topPadX); + } + } + else if (delta < 0) { + + if(topPadX>0){ + topPadX -=1; + gameDisplay.setTop(topPadX); + } + } + + gameDisplay.repaint(); + } + + @Override + public void keyPressed(KeyEvent e) { + + // TODO Auto-generated method stub + int code = e.getKeyCode(); // get which key is pressed + switch (code) { + case KeyEvent.VK_LEFT: + keys.add("LEFT"); + break; + + case KeyEvent.VK_RIGHT: + keys.add("RIGHT"); + break; + } + //gameDisplay.repaint(); + } + + @Override + public void keyReleased(KeyEvent e) { + + // TODO Auto-generated method stub + int code = e.getKeyCode(); // get which key is released + switch (code) { + case KeyEvent.VK_LEFT: + keys.remove("LEFT"); + break; + case KeyEvent.VK_RIGHT: + keys.remove("RIGHT"); + break; + } + } + + @Override + public void keyTyped(KeyEvent e) {} + + } + + + + +} diff --git a/src/startGame/PongGame.java b/src/startGame/PongGame.java new file mode 100644 index 0000000..b28114d --- /dev/null +++ b/src/startGame/PongGame.java @@ -0,0 +1,20 @@ +package startGame; +import model.*; +import view.*; + +public class PongGame { + + public PongGame(){ + + + } + public static void main(String[] args){ + + GameView view = new GameView(); + GameModel model = new GameModel(1,1,2,2,2,2); + GameController controller = new GameController(view, model); + + view.display(); + + } +} diff --git a/src/view/GameView.java b/src/view/GameView.java new file mode 100644 index 0000000..b8a4bcf --- /dev/null +++ b/src/view/GameView.java @@ -0,0 +1,68 @@ +package view; + +import javax.swing.JFrame; + +public class GameView{ + + private Welcome welcome; + private Mode mode; + private PongGameDisplay ponggame; + private Tutorial tutorial; + + private JFrame gameFrame; + + + public GameView(){ + + welcome = new Welcome(); + mode = new Mode(); + ponggame = new PongGameDisplay(); + tutorial = new Tutorial(); + + createGame(); + } + + public void display(){ + welcome.setVisible(true); + } + + + public Welcome getWelcome(){ + return welcome; + } + + public Mode getmode(){ + return mode; + } + + public PongGameDisplay getGame(){ + return ponggame; + } + + public Tutorial getTutorial(){ + return tutorial; + } + + public void createGame(){ + gameFrame = new JFrame("FaultInOurPong"); + gameFrame.setContentPane(ponggame); + gameFrame.setSize(700,500); + gameFrame.setResizable(false); + gameFrame.setLocationRelativeTo(null); + gameFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + } + + public JFrame getGameFrame(){ + return gameFrame; + } + + public int getFrameWidth(){ + return gameFrame.getWidth(); + } + + public int getFrameHeight(){ + return gameFrame.getHeight(); + } + + +} \ No newline at end of file diff --git a/src/view/Mode.java b/src/view/Mode.java new file mode 100644 index 0000000..6d645b1 --- /dev/null +++ b/src/view/Mode.java @@ -0,0 +1,57 @@ +package view; + +import java.awt.event.ActionListener; + +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JPanel; + +import model.*; +import view.*; + +public class Mode extends JFrame{ + + private JButton single = new JButton("Single Player Mode"); + private JButton sObstacle = new JButton("Advanced Single Player Mode"); + + private JPanel buttonPanel; + + public Mode(){ + super("FaultInOurPong"); + this.setSize(700,500); + this.setResizable(false); + this.setLocationRelativeTo(null); + + buttonPanel = new JPanel(); + buttonPanel.setLayout(new BoxLayout(buttonPanel,BoxLayout.Y_AXIS)); + + buttonPanel.add(Box.createVerticalGlue()); + addButton(single); + addButton(sObstacle); + buttonPanel.add(Box.createVerticalGlue()); + + + add(buttonPanel); + this.setDefaultCloseOperation(EXIT_ON_CLOSE); + } + + public void addButton(JButton x) { + x.setMaximumSize(sObstacle.getPreferredSize()); + x.setAlignmentY(CENTER_ALIGNMENT); + x.setAlignmentX(CENTER_ALIGNMENT); + buttonPanel.add(x); + buttonPanel.add(Box.createVerticalStrut(20)); + } + + public void addListener(ActionListener buttonListener){ + single.addActionListener(buttonListener); + sObstacle.addActionListener(buttonListener); + } + + public JButton getSingle(){ + return single; + } + +} diff --git a/src/view/Pong.java b/src/view/Pong.java new file mode 100644 index 0000000..e29eff5 --- /dev/null +++ b/src/view/Pong.java @@ -0,0 +1,12 @@ +package view; + +public class Pong { + + public Pong(){ + + + + } + + +} diff --git a/src/view/PongGameDisplay.java b/src/view/PongGameDisplay.java new file mode 100644 index 0000000..16f7c7f --- /dev/null +++ b/src/view/PongGameDisplay.java @@ -0,0 +1,119 @@ +package view; + +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.event.ActionListener; +import java.awt.event.KeyListener; +import java.awt.geom.Ellipse2D; +import java.awt.geom.Rectangle2D; + +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.Timer; + +public class PongGameDisplay extends JPanel{ + + //private JFrame gameFrame; + private int frameWidth; + private int frameHeight; + + private int scoreTop, scoreBottom; + + private int ballX, ballY; + private int bottomPadX, bottomPadY; + private int topPadX, topPadY; + private boolean first; + private int ballSize; + private int padW, padH; + private int inset; + + + + public PongGameDisplay(){ + first = true; + ballSize = 20; + padW = 80; + padH = 10; + inset = 10; + + scoreTop=0; + scoreBottom=0; + + + + } + + @Override + protected void paintComponent(Graphics g) { + super.paintComponent(g); + Graphics2D g2d = (Graphics2D) g; // create an object for graphics (rectangles) + frameHeight = getHeight(); // get game frame/screen size + frameWidth = getWidth(); + + // initial positioning + if (first) { + bottomPadX = frameWidth / 2 - padW / 2; // setups for the paddles positions - in the middle of the screen + topPadX = bottomPadX; + ballX = frameWidth / 2 - ballSize / 2; // setups for the ball positions - in the middle of the screen + ballY = frameHeight / 2 - ballSize / 2; + first = false; // setup completed + } + + // bottom pad + Rectangle2D bottomPad = new Rectangle(bottomPadX, frameHeight - padH - inset, padW, padH); // creating the object for bottom paddle + g2d.fill(bottomPad); + + // top pad + Rectangle2D topPad = new Rectangle(topPadX, inset, padW, padH); // creating paddle object for the top paddle + g2d.fill(topPad); + + // ball + Ellipse2D ball = new Ellipse2D.Double(ballX, ballY, 20, 20); // creating the ball object for the game + g2d.fill(ball); + + // scores + String scoreB = "Bottom: " + scoreBottom; // saving the score of the bottom paddle + String scoreT = "Top: " + scoreTop; // saving the score of the top paddle + g2d.drawString(scoreB, 10, frameHeight / 2); // printing the score of the bottom paddle in the screen + g2d.drawString(scoreT, frameWidth - 50, frameHeight / 2); // printing the score of the top paddle in the screen + } + + +/* + public void addListener(ActionListener listener){ + //ballX = 40; + //ballY = 40; + + //System.out.println("keylistener"); + repaint(); + } +*/ + + + public void setBall(int x, int y){ + ballX = x; + ballY = y; + } + + public void setBottom(int x){ + bottomPadX = x; + } + + public void setTop(int x){ + topPadX = x; + } + + public int getBottom(){ + return bottomPadX; + } + + public void setTopScore(int s){ + scoreTop=s; + } + + public void setBottomScore(int s){ + scoreBottom = s; + } + +} diff --git a/src/view/Tutorial.java b/src/view/Tutorial.java new file mode 100644 index 0000000..70d03e6 --- /dev/null +++ b/src/view/Tutorial.java @@ -0,0 +1,8 @@ +package view; + +public class Tutorial { + + public Tutorial(){ + + } +} diff --git a/src/view/Welcome.java b/src/view/Welcome.java new file mode 100644 index 0000000..cb0a2b9 --- /dev/null +++ b/src/view/Welcome.java @@ -0,0 +1,60 @@ +package view; + +import java.awt.event.ActionListener; + +import javax.swing.*; + +public class Welcome extends JFrame { + + private JButton start = new JButton("Start New Game"); + private JButton load = new JButton("Load Game"); + private JButton highScores = new JButton("High Scores"); + private JButton tutorial = new JButton("Tutorial"); + private JButton exit = new JButton("Exit"); + + private JPanel buttonPanel; + + public Welcome(){ + + super("FaultInOurPong"); + this.setSize(700,500); + this.setResizable(false); + this.setLocationRelativeTo(null); + + buttonPanel = new JPanel(); + buttonPanel.setLayout(new BoxLayout(buttonPanel,BoxLayout.Y_AXIS)); + + buttonPanel.add(Box.createVerticalGlue()); + addButton(start); + addButton(load); + addButton(highScores); + addButton(tutorial); + addButton(exit); + buttonPanel.add(Box.createVerticalGlue()); + + + add(buttonPanel); + this.setDefaultCloseOperation(EXIT_ON_CLOSE); + + } + + public JButton getStart(){ + return start; + } + + public void addButton(JButton x) { + x.setMaximumSize(start.getPreferredSize()); + x.setAlignmentY(CENTER_ALIGNMENT); + x.setAlignmentX(CENTER_ALIGNMENT); + buttonPanel.add(x); + buttonPanel.add(Box.createVerticalStrut(20)); + } + + public void addListener(ActionListener buttonListener){ + start.addActionListener(buttonListener); + load.addActionListener(buttonListener); + highScores.addActionListener(buttonListener); + tutorial.addActionListener(buttonListener); + exit.addActionListener(buttonListener); + } +} -- GitLab