Мой учитель однажды сказал мне, что я должен попытаться запрограммировать игру в пинг-понг, используя паттерн контроллера вида модели. Существует множество теорий о том, что такое MVC, но если приведен пример, он очень часто проще, чем pong, или применяется к другому домену, например, Java серверные страницы или ADO. NET.
Я попробовал кое-что, чем хочу поделиться с вами. Я полагаю, что совсем не так, как этого хотел мой учитель, а лишь то, насколько я понимаю. Кстати, это написано в Java.
package pong.controller;
import pong.model.BallModel;
public class BallController{
public BallModel ballModel;
public BallController(BallModel ballModel){
this.ballModel = ballModel;
}
/**
* The opponent always serves
*/
public void serve() {
ballModel.x = 50;
ballModel.y = 50;
// update ball in view
ballModel.dy = 0;
ballModel.dx = 4;
// stopped = false;
}
}
И еще есть Контроллер с одним чудовищным методом. Это довольно плохо.
package pong.controller;
import pong.model.*;
import pong.view.*;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import pong.view.BallView;
public class TickListener implements ActionListener{
private TimerModel model; // What model class?
private TimerView view;
TickListener(Model model, View view){
this.model = model;
this.view = view;
}
void initCtrl() {
model.table.setBounds(10, 10, view.frame.getWidth()-20, view.frame.getHeight()-100);
model.r1.x = model.table.getWidth() - 10;
model.ball.y = model.table.getHeight() / 2;
}
/**
* Timer_tick
*/
@Override
public void actionPerformed(ActionEvent e) {
/**
* Angle of rebound is being calculated. Only occurs if the ball is
* on the right / left side.
*/
if (ball.x > (table.getWidth() - ball.width - r1.width)) {
if ((ball.y > r1.y - ball.height) && (ball.y < r1.y + r1.getHeight())) {
dy = (int) (0.2 * (ball.y + ball.height / 2 - (r1.y + r1.height / 2)));
dx *= -1;
} else {
opponent++;
// update label
if (opponent> 5) {
message = "Game Over!";
ball.dy = 0;
ball.dx = 0;
// Timer stop
} else {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
anspiel();
}
}
}
if (ball.x <= r2.width) {
if ((ball.y + ball.height > r2.y) && (ball.y < r2.y + r2.height)) {
dy = (int) (0.2 * (ball.y + ball.height / 2 - (r2.y + r2.height / 2)));
dx *= -1;
} else {
player++;
// update label
if (player > 5) {
message = "You won!";
ball.dy = 0;
ball.dx = 0;
} else {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
serve();
}
}
}
/**
* Ball on the upper / lower bound
*/
if (ball.y > table.getHeight() - ball.height || ball.y <= 0) {
dy *= -1;
}
/**
* Velocity of the ball
*/
ball.x += dx;
ball.y += dy;
/**
* Minimal AI of the opponents paddle
*/
if (ball.y > r2.y + r2.height) {
if (r2.y + r2.height < table.getHeight()) {
r2.y += 2;
}
} else if (ball.y < r2.y + r2.height / 2) {
if (r2.y > 0) {
r2.y -= 2;
}
}
}
}
Последний, которым я хочу поделиться, является самой большой частью представления.
package pong.view;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import pong.controller.TableController;
import pong.model.TableModel;
import pong.model.TischModel;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.util.ArrayList;
public class TableView extends JPanel { // this addActionListener this
ArrayList<Drawable> drawObj;
PongTableModel tableModel;
public TischView(PongTableModel tableModel){
this.tableModel= tableModel;
drawObj = new ArrayList<Drawable>();
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
for(Drawable obj : drawObj) {
obj.draw(g2d);
}
g2d.setPaint(Color.yellow);
g2d.fill(model.ball);
g2d.setPaint(Color.black);
g2d.fill(model.r1);
g2d.fill(model.r2);
g2d.setFont(font);
g2d.drawString(model.opponent + ":" + model.player, model.table.getWidth() / 2, 25);
if(model.stopped) {
g2d.setPaint(Color.red);
g2d.drawString(model.message, model.table.getWidth() / 2, 50);
}
}
}
Одна вещь, которая может оказаться полезной, - это структура проекта.
пакет контроллер
- BallController. java
- PaddleController. java
- TickListener. java
- TableController. java
пакет модель
- BallModel. java
- модель. java
- PaddleModel. java
- PongTableModel. java
пакет просмотр
- BallView . java
- Drawable. java
- FrameView. java
- PaddleView. java
- TableView. java
пакет средство запуска
Есть ли у вас какие-либо предложения о том, как структурировать этот код в разумная манера? Я действительно "гуглил" много, но не могу понять смысл материала, предоставленного онлайн. Это даже не компилируется больше. Те, что выше, являются только выдержками. Возможно, мне придется написать электронное письмо моему учителю, чтобы это понять.