Skip to content
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

Update MainApplicationFrame.java #64

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
138 changes: 15 additions & 123 deletions robots/src/gui/GameVisualizer.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,27 @@
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JPanel;
import javax.swing.*;

import static gui.RobotModel.round;

public class GameVisualizer extends JPanel
{
public RobotModel robotModel = new RobotModel();
public RobotCoordinatesWindow robotCoordinatesWindow = new RobotCoordinatesWindow(robotModel);
private final Timer m_timer = initTimer();

private static 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()
public GameVisualizer()
{
m_timer.schedule(new TimerTask()
{
Expand All @@ -48,128 +39,31 @@ public void run()
@Override
public void run()
{
onModelUpdateEvent();
robotModel.onModelUpdateEvent();
}
}, 0, 10);
addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
setTargetPosition(e.getPoint());
robotModel.setTargetPosition(e.getPoint());
repaint();
}
});
setDoubleBuffered(true);
}

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

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

@Override
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);
Graphics2D g2d = (Graphics2D)g;
drawRobot(g2d, round(robotModel.m_robotPositionX), round(robotModel.m_robotPositionY), robotModel.m_robotDirection);
drawTarget(g2d, robotModel.m_targetPositionX, robotModel.m_targetPositionY);
}

private static void fillOval(Graphics g, int centerX, int centerY, int diam1, int diam2)
Expand All @@ -181,12 +75,11 @@ private static void drawOval(Graphics g, int centerX, int centerY, int diam1, in
{
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);
int robotCenterX = round(robotModel.m_robotPositionX);
int robotCenterY = round(robotModel.m_robotPositionY);
AffineTransform t = AffineTransform.getRotateInstance(robotModel.m_robotDirection, robotCenterX, robotCenterY);
g.setTransform(t);
g.setColor(Color.MAGENTA);
fillOval(g, robotCenterX, robotCenterY, 30, 10);
Expand All @@ -197,7 +90,6 @@ 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);
Expand Down
18 changes: 11 additions & 7 deletions robots/src/gui/GameWindow.java
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
package gui;

import java.awt.BorderLayout;
import java.util.ResourceBundle;

import javax.swing.JInternalFrame;
import javax.swing.JPanel;

public class GameWindow extends JInternalFrame
{
private final GameVisualizer m_visualizer;
public GameWindow()
{
super("Игровое поле", true, true, true, true);
m_visualizer = new GameVisualizer();
public class GameWindow extends JInternalFrame {
public final GameVisualizer m_visualizer = new GameVisualizer();
//private ResourceBundle messages;

public GameWindow() {
super(MainApplicationFrame.messages.getString("game.window.title"), true, true, true, true);
JPanel panel = new JPanel(new BorderLayout());
panel.add(m_visualizer, BorderLayout.CENTER);
getContentPane().add(panel);
pack();
}

public void updateTitle() {
setTitle(MainApplicationFrame.messages.getString("game.window.title"));
}
}
7 changes: 6 additions & 1 deletion robots/src/gui/LogWindow.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public class LogWindow extends JInternalFrame implements LogChangeListener

public LogWindow(LogWindowSource logSource)
{
super("Протокол работы", true, true, true, true);
super(MainApplicationFrame.messages.getString("protocol.window.title"), true, true, true, true);
m_logSource = logSource;
m_logSource.registerListener(this);
m_logContent = new TextArea("");
Expand All @@ -29,6 +29,7 @@ public LogWindow(LogWindowSource logSource)
getContentPane().add(panel);
pack();
updateLogContent();
updateTitleP();
}

private void updateLogContent()
Expand All @@ -40,6 +41,10 @@ private void updateLogContent()
}
m_logContent.setText(content.toString());
m_logContent.invalidate();
updateTitleP();
}
public void updateTitleP() {
setTitle(MainApplicationFrame.messages.getString("protocol.window.title"));
}

@Override
Expand Down
Loading