forked from alklepin/Robots-old
-
Notifications
You must be signed in to change notification settings - Fork 0
Start task2 #2
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
Open
As-pasa
wants to merge
34
commits into
master
Choose a base branch
from
startTask2
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Start task2 #2
Changes from all commits
Commits
Show all changes
34 commits
Select commit
Hold shift + click to select a range
17510b6
initial configure
As-pasa e6b60ee
drawing logic incapsulated in drawModels, removed service math functi…
As-pasa 83d0262
robot movement logic incapsulated into RobotModel class, unused funct…
As-pasa 33340f8
robot internal variable dublicates removed from GameVisualizer, repla…
As-pasa 41ad220
model update timer incapsulated into controller class, model update c…
As-pasa 069627a
created PositionShowWinow, representing position of model
As-pasa a370a85
start task 3: robot rotation bug fixed
As-pasa 0b0863b
window redraw for GameVisualizer and PosotionShowWindow moved to daem…
As-pasa 806a355
added dependency (model, controller) for MainApplicationFrame
As-pasa 2c47c4c
Controller package and Controller class renamed
As-pasa 75e4493
setting position logic separated from update timer
As-pasa 81cadba
redraw timer removed from GameVisualizer. Now redraw is triggered by …
As-pasa ec0b6cc
target point incapsulated into separate model, changed dependency for…
As-pasa 50557b7
Drawable interface cleared from static functions. Added utils package
As-pasa ebe5aca
target model is now dependency for visualisation
As-pasa 1a72771
getters in models changed to global getPos method. Potentially fixing…
As-pasa 089875b
RobotModel class cleared from static math function, that now placed i…
As-pasa c4e425e
TargetModel now extends Observable
As-pasa 7a3f520
refactor: CoordPair class renamed into Vector
As-pasa bb526be
Naming changes, changed signature for RobotRepresentation constructor…
As-pasa 9e19d4d
vector class removed, added state hierarchie
As-pasa 46378d6
renamed getPos method to getState in RobotModel and TargetModel
As-pasa c0c0b0e
listener for application closure added
As-pasa 96b585f
dirty serialization logic added. No Logger saving
As-pasa fd97fb4
added serialization container for logWindowSource, added method of ge…
As-pasa 1fb164f
serialization markup for log message components
As-pasa 2302b8f
logSource is now a property of main program and dependency for graphi…
As-pasa f5d81fb
minor linter refactor
As-pasa 8aacbe3
GameVisualizer import cleaning
As-pasa 457e18d
serialization logic generalized.
As-pasa 44746e6
debug messages removed, unused import removed
As-pasa ed69381
initialization logic refactored
As-pasa 49e45d1
config writer and reader replaced with general objectFileStream logic
As-pasa 77b9dc5
fixed bug with empty files, removved hard-coded file names
As-pasa File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,6 @@ | ||
| /.metadata | ||
| /robots/.settings | ||
| /robots/bin | ||
| eclipse.bat | ||
| eclipse.bat | ||
| /out/ | ||
| /.idea/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| package config; | ||
|
|
||
| import java.io.File; | ||
|
|
||
| public interface FileSupplier { | ||
| File getFile(); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| package config; | ||
|
|
||
| import java.io.File; | ||
|
|
||
| public class PredeterminedPathFileSupplier implements FileSupplier{ | ||
| private File path; | ||
|
|
||
| public PredeterminedPathFileSupplier(String path) { | ||
| this.path = new File(path); | ||
| } | ||
|
|
||
| @Override | ||
| public File getFile() { | ||
| return path; | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| package controllers; | ||
|
|
||
| import models.RobotModel; | ||
|
|
||
| import java.util.Timer; | ||
| import java.util.TimerTask; | ||
|
|
||
| public class RobotUpdateController { | ||
|
|
||
| private final Timer m_timer = initTimer(); | ||
| private RobotModel m_model; | ||
| private static Timer initTimer() { | ||
| Timer timer = new Timer("events generator", true); | ||
| return timer; | ||
| } | ||
| public RobotUpdateController(RobotModel model){ | ||
| m_model=model; | ||
| m_timer.schedule(new TimerTask() { | ||
| @Override | ||
| public void run() { | ||
| updateModel(); | ||
| } | ||
| }, 0, 10); | ||
| } | ||
|
|
||
| public void updateModel(){ | ||
| m_model.updatePos(); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| package controllers; | ||
|
|
||
| import models.TargetModel; | ||
|
|
||
| import java.awt.*; | ||
|
|
||
| public class TargetPositionController { | ||
| private TargetModel m_model; | ||
|
|
||
|
|
||
| public TargetPositionController(TargetModel model){ | ||
| m_model=model; | ||
| } | ||
| public void setTargetPos(Point p){ | ||
| m_model.setPos(p.x,p.y); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,210 +1,81 @@ | ||
| package gui; | ||
|
|
||
| import java.awt.Color; | ||
| import java.awt.EventQueue; | ||
| import java.awt.Graphics; | ||
| import java.awt.Graphics2D; | ||
| import java.awt.Point; | ||
| import controllers.TargetPositionController; | ||
| import gui.drawModels.RobotRepresentation; | ||
| import gui.drawModels.TargetRepresentation; | ||
|
|
||
| import models.RobotModel; | ||
| import models.TargetModel; | ||
|
|
||
| import java.awt.*; | ||
| import java.awt.event.MouseAdapter; | ||
| import java.awt.event.MouseEvent; | ||
| import java.awt.geom.AffineTransform; | ||
| import java.util.Timer; | ||
| import java.util.TimerTask; | ||
| import java.util.Observable; | ||
| import java.util.Observer; | ||
|
|
||
| import javax.swing.JPanel; | ||
|
|
||
| public class GameVisualizer extends JPanel | ||
| { | ||
| private final Timer m_timer = initTimer(); | ||
|
|
||
| private static Timer initTimer() | ||
| { | ||
| Timer timer = new Timer("events generator", true); | ||
| return timer; | ||
| } | ||
|
|
||
| private volatile double m_robotPositionX = 100; | ||
| private volatile double m_robotPositionY = 100; | ||
| private volatile double m_robotDirection = 0; | ||
|
|
||
| private volatile int m_targetPositionX = 150; | ||
| private volatile int m_targetPositionY = 100; | ||
|
|
||
| private static final double maxVelocity = 0.1; | ||
| private static final double maxAngularVelocity = 0.001; | ||
|
|
||
| public GameVisualizer() | ||
| { | ||
| m_timer.schedule(new TimerTask() | ||
| { | ||
| @Override | ||
| public void run() | ||
| { | ||
| onRedrawEvent(); | ||
| } | ||
| }, 0, 50); | ||
| m_timer.schedule(new TimerTask() | ||
| { | ||
| @Override | ||
| public void run() | ||
| { | ||
| onModelUpdateEvent(); | ||
| } | ||
| }, 0, 10); | ||
| addMouseListener(new MouseAdapter() | ||
| { | ||
| public class GameVisualizer extends JPanel implements Observer{ | ||
|
|
||
|
|
||
|
|
||
| private RobotRepresentation m_robotView; | ||
| private TargetRepresentation m_targetView; | ||
|
|
||
| private TargetPositionController m_targetController; | ||
| private RobotModel m_robot; | ||
|
|
||
|
|
||
|
|
||
|
|
||
| public GameVisualizer(TargetPositionController modelController, RobotModel model, TargetModel target) { | ||
|
|
||
| m_robot =model; | ||
| m_robotView = new RobotRepresentation(m_robot); | ||
| m_targetView = new TargetRepresentation(target); | ||
| m_targetController = modelController; | ||
|
|
||
| addMouseListener(new MouseAdapter() { | ||
| @Override | ||
| public void mouseClicked(MouseEvent e) | ||
| { | ||
| public void mouseClicked(MouseEvent e) { | ||
| setTargetPosition(e.getPoint()); | ||
| repaint(); | ||
| } | ||
| }); | ||
| setDoubleBuffered(true); | ||
| } | ||
|
|
||
| protected void setTargetPosition(Point p) | ||
| { | ||
| m_targetPositionX = p.x; | ||
| m_targetPositionY = p.y; | ||
| protected void setTargetPosition(Point p) { | ||
|
|
||
|
|
||
| m_targetController.setTargetPos(p); | ||
| } | ||
|
|
||
| protected void onRedrawEvent() | ||
| { | ||
|
|
||
| protected void onRedrawEvent() { | ||
| EventQueue.invokeLater(this::repaint); | ||
| } | ||
|
|
||
| private static double distance(double x1, double y1, double x2, double y2) | ||
| { | ||
| double diffX = x1 - x2; | ||
| double diffY = y1 - y2; | ||
| return Math.sqrt(diffX * diffX + diffY * diffY); | ||
| } | ||
|
|
||
| private static double angleTo(double fromX, double fromY, double toX, double toY) | ||
| { | ||
| double diffX = toX - fromX; | ||
| double diffY = toY - fromY; | ||
|
|
||
| return asNormalizedRadians(Math.atan2(diffY, diffX)); | ||
| } | ||
|
|
||
| protected void onModelUpdateEvent() | ||
| { | ||
| double distance = distance(m_targetPositionX, m_targetPositionY, | ||
| m_robotPositionX, m_robotPositionY); | ||
| if (distance < 0.5) | ||
| { | ||
| return; | ||
| } | ||
| double velocity = maxVelocity; | ||
| double angleToTarget = angleTo(m_robotPositionX, m_robotPositionY, m_targetPositionX, m_targetPositionY); | ||
| double angularVelocity = 0; | ||
| if (angleToTarget > m_robotDirection) | ||
| { | ||
| angularVelocity = maxAngularVelocity; | ||
| } | ||
| if (angleToTarget < m_robotDirection) | ||
| { | ||
| angularVelocity = -maxAngularVelocity; | ||
| } | ||
|
|
||
| moveRobot(velocity, angularVelocity, 10); | ||
| } | ||
|
|
||
| private static double applyLimits(double value, double min, double max) | ||
| { | ||
| if (value < min) | ||
| return min; | ||
| if (value > max) | ||
| return max; | ||
| return value; | ||
| } | ||
|
|
||
| private void moveRobot(double velocity, double angularVelocity, double duration) | ||
| { | ||
| velocity = applyLimits(velocity, 0, maxVelocity); | ||
| angularVelocity = applyLimits(angularVelocity, -maxAngularVelocity, maxAngularVelocity); | ||
| double newX = m_robotPositionX + velocity / angularVelocity * | ||
| (Math.sin(m_robotDirection + angularVelocity * duration) - | ||
| Math.sin(m_robotDirection)); | ||
| if (!Double.isFinite(newX)) | ||
| { | ||
| newX = m_robotPositionX + velocity * duration * Math.cos(m_robotDirection); | ||
| } | ||
| double newY = m_robotPositionY - velocity / angularVelocity * | ||
| (Math.cos(m_robotDirection + angularVelocity * duration) - | ||
| Math.cos(m_robotDirection)); | ||
| if (!Double.isFinite(newY)) | ||
| { | ||
| newY = m_robotPositionY + velocity * duration * Math.sin(m_robotDirection); | ||
| } | ||
| m_robotPositionX = newX; | ||
| m_robotPositionY = newY; | ||
| double newDirection = asNormalizedRadians(m_robotDirection + angularVelocity * duration); | ||
| m_robotDirection = newDirection; | ||
| } | ||
|
|
||
| private static double asNormalizedRadians(double angle) | ||
| { | ||
| while (angle < 0) | ||
| { | ||
| angle += 2*Math.PI; | ||
| } | ||
| while (angle >= 2*Math.PI) | ||
| { | ||
| angle -= 2*Math.PI; | ||
| } | ||
| return angle; | ||
| } | ||
|
|
||
| private static int round(double value) | ||
| { | ||
| return (int)(value + 0.5); | ||
| protected void onModelUpdateEvent() { | ||
| onRedrawEvent(); | ||
| } | ||
|
|
||
|
|
||
|
|
||
| @Override | ||
| public void paint(Graphics g) | ||
| { | ||
| public void paint(Graphics g) { | ||
| super.paint(g); | ||
| Graphics2D g2d = (Graphics2D)g; | ||
| drawRobot(g2d, round(m_robotPositionX), round(m_robotPositionY), m_robotDirection); | ||
| drawTarget(g2d, m_targetPositionX, m_targetPositionY); | ||
| } | ||
|
|
||
| private static void fillOval(Graphics g, int centerX, int centerY, int diam1, int diam2) | ||
| { | ||
| g.fillOval(centerX - diam1 / 2, centerY - diam2 / 2, diam1, diam2); | ||
| } | ||
|
|
||
| private static void drawOval(Graphics g, int centerX, int centerY, int diam1, int diam2) | ||
| { | ||
| g.drawOval(centerX - diam1 / 2, centerY - diam2 / 2, diam1, diam2); | ||
| } | ||
|
|
||
| private void drawRobot(Graphics2D g, int x, int y, double direction) | ||
| { | ||
| int robotCenterX = round(m_robotPositionX); | ||
| int robotCenterY = round(m_robotPositionY); | ||
| AffineTransform t = AffineTransform.getRotateInstance(direction, robotCenterX, robotCenterY); | ||
| g.setTransform(t); | ||
| g.setColor(Color.MAGENTA); | ||
| fillOval(g, robotCenterX, robotCenterY, 30, 10); | ||
| g.setColor(Color.BLACK); | ||
| drawOval(g, robotCenterX, robotCenterY, 30, 10); | ||
| g.setColor(Color.WHITE); | ||
| fillOval(g, robotCenterX + 10, robotCenterY, 5, 5); | ||
| g.setColor(Color.BLACK); | ||
| drawOval(g, robotCenterX + 10, robotCenterY, 5, 5); | ||
| Graphics2D g2d = (Graphics2D) g; | ||
| m_robotView.draw(g2d); | ||
| m_targetView.draw(g2d); | ||
|
|
||
| } | ||
|
|
||
| private void drawTarget(Graphics2D g, int x, int y) | ||
| { | ||
| AffineTransform t = AffineTransform.getRotateInstance(0, 0, 0); | ||
| g.setTransform(t); | ||
| g.setColor(Color.GREEN); | ||
| fillOval(g, x, y, 5, 5); | ||
| g.setColor(Color.BLACK); | ||
| drawOval(g, x, y, 5, 5); | ||
|
|
||
|
|
||
| @Override | ||
| public void update(Observable o, Object arg) { | ||
| EventQueue.invokeLater(this::onModelUpdateEvent); | ||
| } | ||
|
|
||
|
|
||
|
|
||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,20 +1,36 @@ | ||
| package gui; | ||
|
|
||
| import controllers.TargetPositionController; | ||
| import gui.serial.SerializableFrame; | ||
| import models.RobotModel; | ||
| import models.TargetModel; | ||
| import windowConstructors.GameWindowConstructor; | ||
| import windowConstructors.WindowConstructor; | ||
|
|
||
|
|
||
| import java.awt.BorderLayout; | ||
|
|
||
| import javax.swing.JInternalFrame; | ||
| import javax.swing.JPanel; | ||
|
|
||
| public class GameWindow extends JInternalFrame | ||
| public class GameWindow extends JInternalFrame implements SerializableFrame | ||
| { | ||
| private final GameVisualizer m_visualizer; | ||
| public GameWindow() | ||
| public GameWindow(RobotModel model, TargetPositionController controller, TargetModel target) | ||
| { | ||
| super("Игровое поле", true, true, true, true); | ||
| m_visualizer = new GameVisualizer(); | ||
|
|
||
| m_visualizer = new GameVisualizer(controller,model,target); | ||
| model.addObserver(m_visualizer); | ||
| JPanel panel = new JPanel(new BorderLayout()); | ||
| panel.add(m_visualizer, BorderLayout.CENTER); | ||
| getContentPane().add(panel); | ||
| pack(); | ||
| } | ||
|
|
||
|
|
||
| @Override | ||
| public WindowConstructor getFrameState() { | ||
| return new GameWindowConstructor(getX(),getY(),getSize().width,getSize().height); | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
А зачем так усложнять код? Почему было просто не использовать File в качестве абстракции для представления целевого файла? :)
Я бы понял смысл этой абстракции, если бы предполагалась возможность изменять эти целевые файлы на ходу. Но тогда было бы правильнее просто ввести сущность для хранения конфигурации приложения, где были бы, в частности, нужные данные о файлах.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Я как раз предполагал возможность использования окна выбора файлов(JFileChooser). Мне казалось что абстрагироваться от способа задачи файла хардкодом/выбором с помощью пользовательского интерфейса было бы неплохо. Но логика не была реализована, так что пока это действительно абстракция ради абстракции
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P.S. не до конца прочитал ваше предолжение о новой сущности+выяснил что логика работы с JFileChooser не является блокирующией и текущая система абстракций все равно не позволит без костылей добавить этот функционал