Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion robots/src/main/gui/AbstractWindow.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public abstract class AbstractWindow extends JInternalFrame implements WithState
prefixWindowSizeHeight = formatTitle("size height");
}

public AbstractWindow() {
public AbstractWindow(String окноСостоянияРобота) {
super();
}

Expand Down
40 changes: 40 additions & 0 deletions robots/src/main/gui/CoordinatsWindow.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package gui;

import model.Robot;

import java.awt.*;
import java.util.Observable;
import java.util.Observer;

import javax.swing.*;

public class CoordinatsWindow extends AbstractWindow implements Observer {
private Robot robot;
private JTextArea textField;

public CoordinatsWindow(Robot robot){
super("Окно состояния робота");
JPanel panel = new JPanel(new BorderLayout());

textField = new JTextArea();
panel.add(textField, BorderLayout.CENTER);

getContentPane().add(panel);
pack();

this.robot = robot;
robot.addObserver(this);
}

@Override
public void update(Observable o, Object arg) {
if (o.equals(robot)) {
if (arg.equals("robot moved"))
onRobotMoved();
}
}

private void onRobotMoved() {
textField.setText(robot.getInfo());
}
}
191 changes: 52 additions & 139 deletions robots/src/main/gui/GameVisualizer.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package gui;

import model.Robot;

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
Expand All @@ -8,185 +10,97 @@
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;

import java.util.Observer;
import java.util.Observable;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JPanel;

public class GameVisualizer extends JPanel
public class GameVisualizer extends JPanel implements Observer
{
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 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()

private final Robot robot;

public GameVisualizer(Robot robot)
{
m_timer.schedule(new TimerTask()
{
Timer m_timer = new Timer("events generator", true);

m_timer.schedule(new TimerTask() {
@Override
public void run()
{
public void run() {
onRedrawEvent();
}
}, 0, 50);
m_timer.schedule(new TimerTask()
{
m_timer.schedule(new TimerTask() {
@Override
public void run()
{
onModelUpdateEvent();
public void run() {
robot.update(m_targetPositionX, m_targetPositionY);
}
}, 0, 10);
addMouseListener(new MouseAdapter()
{
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e)
{
public void mouseClicked(MouseEvent e) {
setTargetPosition(e.getPoint());
repaint();
}
});
setDoubleBuffered(true);

this.robot = robot;
robot.addObserver(this);
}

protected void setTargetPosition(Point p)
{
protected void setTargetPosition(Point p) {
m_targetPositionX = p.x;
m_targetPositionY = p.y;
}

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;
@Override
public void update(Observable o, Object arg){
if (o.equals(robot))
if (arg.equals("robot moved")){
m_robotPositionX = robot.getRobotPositionX();
m_robotPositionY = robot.getRobotPositionY();
m_robotDirection = robot.getRobotDirection();
}
}

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)
{
private static int round(double value) {
return (int)(value + 0.5);
}

@Override
public void paint(Graphics g)
{
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D)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)
{

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)
{

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

private void drawRobot(Graphics2D g, int x, int y, double direction) {
int robotCenterX = round(x);
int robotCenterY = round(y);
AffineTransform t = AffineTransform.getRotateInstance(direction, robotCenterX, robotCenterY);
g.setTransform(t);
g.setColor(Color.MAGENTA);
fillOval(g, robotCenterX, robotCenterY, 30, 10);
Expand All @@ -197,14 +111,13 @@ private void drawRobot(Graphics2D g, int x, int y, double direction)
g.setColor(Color.BLACK);
drawOval(g, robotCenterX + 10, robotCenterY, 5, 5);
}

private void drawTarget(Graphics2D g, int x, int y)
{
AffineTransform t = AffineTransform.getRotateInstance(0, 0, 0);

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);
}
}
}
26 changes: 7 additions & 19 deletions robots/src/main/gui/GameWindow.java
Original file line number Diff line number Diff line change
@@ -1,33 +1,21 @@
package gui;

import java.awt.BorderLayout;

import java.awt.*;
import javax.swing.JPanel;

import model.Robot;

public class GameWindow extends AbstractWindow
{
private final GameVisualizer m_visualizer;

public GameWindow() {
super();

setTitle("Игровое окно");
setResizable(true);
setClosable(true);
setMaximizable(true);
setIconifiable(true);

m_visualizer = new GameVisualizer();
public GameWindow(Robot robot)
{
super("Игровое поле");
m_visualizer = new GameVisualizer(robot);
JPanel panel = new JPanel(new BorderLayout());
panel.add(m_visualizer, BorderLayout.CENTER);
getContentPane().add(panel);
pack();
}

@Override
public void dispose() {
// m_visualizer.stopTimer();

super.dispose();
}
}
2 changes: 1 addition & 1 deletion robots/src/main/gui/LogWindow.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public class LogWindow extends AbstractWindow implements LogChangeListener
private final TextArea m_logContent;

public LogWindow(LogWindowSource logSource) {
super();
super("Окно состояния робота");

setTitle("Окно логов");
setResizable(true);
Expand Down
13 changes: 9 additions & 4 deletions robots/src/main/gui/MainApplicationFrame.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@

package gui;

import model.Robot;

import java.awt.*;
import java.awt.event.*;
import java.util.ResourceBundle;
Expand Down Expand Up @@ -39,9 +40,10 @@ public void windowClosing(WindowEvent e) {
}
private JDesktopPane createDesktopPane() {
desktopPane = new JDesktopPane();

Robot robot = new Robot(100, 100);
addWindow(createLogWindow(), 300, 800);
addWindow(new GameWindow(), 400, 400);
addWindow(new GameWindow(robot), 400, 400);
addWindow(new CoordinatsWindow(robot), 200, 200);

for (JInternalFrame frame : desktopPane.getAllFrames()) {
((AbstractWindow) frame).loadWindow();
Expand Down Expand Up @@ -82,11 +84,14 @@ private JMenu createFileMenu() {
menu.setMnemonic(KeyEvent.VK_D);

menu.add(createMenuItem(messages.getString("NewGameWindow"), KeyEvent.VK_N, KeyStroke.getKeyStroke(KeyEvent.VK_R, ActionEvent.ALT_MASK), (event) -> {
GameWindow window = new GameWindow();
Robot robot = new Robot(100, 100);
GameWindow window = new GameWindow(robot);
addWindow(window, 400, 400);
addWindow(new CoordinatsWindow(robot), 200, 200);
}));



menu.add(createMenuItem(messages.getString("LogsWindow"), KeyEvent.VK_L, KeyStroke.getKeyStroke(KeyEvent.VK_L, ActionEvent.ALT_MASK), (event) -> {
LogWindow window = new LogWindow(Logger.getDefaultLogSource());
addWindow(window, 150, 350);
Expand Down
Loading