Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 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
e364c98
#3 added color variaty for RobotRepresentation
As-pasa May 17, 2023
242a4e6
#3 robot customisation added
As-pasa May 17, 2023
15443cf
#3 RobotRepresentation refactored
As-pasa May 17, 2023
6775a95
#3 initialized own task 1: color customization. Inner structure of ro…
As-pasa May 22, 2023
4237b07
#3 RobotWardrobeWindow constructor logic generalized with terms conce…
As-pasa May 22, 2023
6e9c61d
#3 change of TargetRepresentation to term model
As-pasa May 23, 2023
53879b9
#3 added offset sliders for term customization
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/
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);
}
}
238 changes: 54 additions & 184 deletions robots/src/gui/GameVisualizer.java
Original file line number Diff line number Diff line change
@@ -1,210 +1,80 @@
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;
private TargetModel m_target;




public GameVisualizer(TargetPositionController modelController, RobotModel model, TargetModel target, RobotRepresentation robotView) {

m_robot =model;
m_target=target;
m_robotView = robotView;
m_targetView = new TargetRepresentation();
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_robot);
m_targetView.draw(g2d, m_target);

}

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);
}

}
12 changes: 10 additions & 2 deletions robots/src/gui/GameWindow.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
package gui;

import controllers.TargetPositionController;
import gui.drawModels.RobotRepresentation;
import models.RobotModel;
import models.TargetModel;


import java.awt.BorderLayout;

import javax.swing.JInternalFrame;
Expand All @@ -8,10 +14,12 @@
public class GameWindow extends JInternalFrame
{
private final GameVisualizer m_visualizer;
public GameWindow()
public GameWindow(RobotModel model, TargetPositionController controller, TargetModel target, RobotRepresentation robotView)
{
super("Игровое поле", true, true, true, true);
m_visualizer = new GameVisualizer();

m_visualizer = new GameVisualizer(controller,model,target,robotView);
model.addObserver(m_visualizer);
JPanel panel = new JPanel(new BorderLayout());
panel.add(m_visualizer, BorderLayout.CENTER);
getContentPane().add(panel);
Expand Down
19 changes: 16 additions & 3 deletions robots/src/gui/MainApplicationFrame.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

import controllers.TargetPositionController;
import gui.drawModels.RobotRepresentation;
import log.Logger;
import models.RobotModel;
import models.TargetModel;

/**
* Что требуется сделать:
Expand All @@ -26,7 +30,7 @@ public class MainApplicationFrame extends JFrame
{
private final JDesktopPane desktopPane = new JDesktopPane();

public MainApplicationFrame() {
public MainApplicationFrame(RobotModel model, TargetPositionController controller, TargetModel target,RobotRepresentation robotView) {
//Make the big window be indented 50 pixels from each edge
//of the screen.
int inset = 50;
Expand All @@ -36,15 +40,24 @@ public MainApplicationFrame() {
screenSize.height - inset*2);

setContentPane(desktopPane);


LogWindow logWindow = createLogWindow();
addWindow(logWindow);

GameWindow gameWindow = new GameWindow();

GameWindow gameWindow = new GameWindow(model,controller,target,robotView);
gameWindow.setSize(400, 400);

PositionShowWindow coordWindow=new PositionShowWindow(model);
coordWindow.setSize(200,100);
addWindow(coordWindow);
addWindow(gameWindow);

RobotWardrobeWindow colorWindow=new RobotWardrobeWindow(robotView);
colorWindow.setSize(400,400);
addWindow(colorWindow);

setJMenuBar(generateMenuBar());
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
Expand Down
Loading