Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
17510b6
initial configure
As-pasa Apr 17, 2023
e6b60ee
drawing logic incapsulated in drawModels, removed service math functi…
As-pasa Apr 18, 2023
83d0262
robot movement logic incapsulated into RobotModel class, unused funct…
As-pasa Apr 18, 2023
33340f8
robot internal variable dublicates removed from GameVisualizer, repla…
As-pasa Apr 18, 2023
41ad220
model update timer incapsulated into controller class, model update c…
As-pasa Apr 18, 2023
069627a
created PositionShowWinow, representing position of model
As-pasa Apr 18, 2023
a370a85
start task 3: robot rotation bug fixed
As-pasa Apr 21, 2023
0b0863b
window redraw for GameVisualizer and PosotionShowWindow moved to daem…
As-pasa Apr 22, 2023
806a355
added dependency (model, controller) for MainApplicationFrame
As-pasa Apr 22, 2023
2c47c4c
Controller package and Controller class renamed
As-pasa May 4, 2023
75e4493
setting position logic separated from update timer
As-pasa May 4, 2023
81cadba
redraw timer removed from GameVisualizer. Now redraw is triggered by …
As-pasa May 4, 2023
ec0b6cc
target point incapsulated into separate model, changed dependency for…
As-pasa May 4, 2023
50557b7
Drawable interface cleared from static functions. Added utils package
As-pasa May 4, 2023
ebe5aca
target model is now dependency for visualisation
As-pasa May 4, 2023
1a72771
getters in models changed to global getPos method. Potentially fixing…
As-pasa May 4, 2023
089875b
RobotModel class cleared from static math function, that now placed i…
As-pasa May 4, 2023
c4e425e
TargetModel now extends Observable
As-pasa May 5, 2023
7a3f520
refactor: CoordPair class renamed into Vector
As-pasa May 5, 2023
bb526be
Naming changes, changed signature for RobotRepresentation constructor…
As-pasa May 11, 2023
9e19d4d
vector class removed, added state hierarchie
As-pasa May 11, 2023
46378d6
renamed getPos method to getState in RobotModel and TargetModel
As-pasa May 11, 2023
c0c0b0e
listener for application closure added
As-pasa May 12, 2023
96b585f
dirty serialization logic added. No Logger saving
As-pasa May 15, 2023
fd97fb4
added serialization container for logWindowSource, added method of ge…
As-pasa May 17, 2023
1fb164f
serialization markup for log message components
As-pasa May 17, 2023
2302b8f
logSource is now a property of main program and dependency for graphi…
As-pasa May 17, 2023
f5d81fb
minor linter refactor
As-pasa Jun 11, 2023
8aacbe3
GameVisualizer import cleaning
As-pasa Jun 11, 2023
457e18d
serialization logic generalized.
As-pasa Jun 11, 2023
44746e6
debug messages removed, unused import removed
As-pasa Jun 12, 2023
ed69381
initialization logic refactored
As-pasa Jun 12, 2023
49e45d1
config writer and reader replaced with general objectFileStream logic
As-pasa Jun 12, 2023
77b9dc5
fixed bug with empty files, removved hard-coded file names
As-pasa Jun 12, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
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/
7 changes: 7 additions & 0 deletions robots/src/config/FileSupplier.java
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();
}
16 changes: 16 additions & 0 deletions robots/src/config/PredeterminedPathFileSupplier.java
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;
}
}
29 changes: 29 additions & 0 deletions robots/src/controllers/RobotUpdateController.java
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();
}
}
17 changes: 17 additions & 0 deletions robots/src/controllers/TargetPositionController.java
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);
}
}
239 changes: 55 additions & 184 deletions robots/src/gui/GameVisualizer.java
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);
}



}
22 changes: 19 additions & 3 deletions robots/src/gui/GameWindow.java
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);
}
}
Loading