forked from alklepin/Robots-old
-
Notifications
You must be signed in to change notification settings - Fork 0
task 3 #3
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
JavaScriptHaters
wants to merge
4
commits into
master
Choose a base branch
from
task-3
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
task 3 #3
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
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 |
|---|---|---|
| @@ -0,0 +1,95 @@ | ||
| package game; | ||
|
|
||
| import java.awt.Color; | ||
| 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.awt.geom.Point2D; | ||
| import java.util.TimerTask; | ||
|
|
||
| import javax.swing.JPanel; | ||
|
|
||
| public class GameVisualizer extends JPanel | ||
| { | ||
| private final RobotLogic logic; | ||
|
|
||
| public GameVisualizer(RobotLogic logic) | ||
| { | ||
| this.logic = logic; | ||
|
|
||
| logic.addActionToTimer(new TimerTask() | ||
| { | ||
| @Override | ||
| public void run() | ||
| { | ||
| repaint(); | ||
| } | ||
| }, 50); | ||
|
|
||
| addMouseListener(new MouseAdapter() | ||
| { | ||
| @Override | ||
| public void mouseClicked(MouseEvent e) | ||
| { | ||
| Point clickPoint = e.getPoint(); | ||
|
|
||
| logic.setTarget(new Target(clickPoint.getX(), clickPoint.getY())); | ||
| logic.setWindowBounds(new Point2D.Double(getWidth(), getHeight())); | ||
| repaint(); | ||
| } | ||
| }); | ||
|
|
||
| setDoubleBuffered(true); | ||
| } | ||
|
|
||
| @Override | ||
| public void paint(Graphics g) | ||
| { | ||
| super.paint(g); | ||
| Graphics2D g2d = (Graphics2D) g; | ||
| drawRobot(g2d, logic.getRobot()); | ||
| drawTarget(g2d, logic.getTarget()); | ||
| } | ||
|
|
||
| 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, Robot robot) | ||
| { | ||
| int robotCenterX = (int) Math.round(robot.getPosition().getX()); | ||
| int robotCenterY = (int) Math.round(robot.getPosition().getY()); | ||
| AffineTransform t = AffineTransform.getRotateInstance(robot.getDirection(), 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); | ||
| } | ||
|
|
||
| private void drawTarget(Graphics2D g, Target target) | ||
| { | ||
| AffineTransform t = AffineTransform.getRotateInstance(0, 0, 0); | ||
| g.setTransform(t); | ||
|
|
||
| g.setColor(Color.GREEN); | ||
| fillOval(g, (int) target.getPosition().getX(), (int) target.getPosition().getY(), 5, 5); | ||
| g.setColor(Color.BLACK); | ||
| drawOval(g, (int) target.getPosition().getX(), (int) target.getPosition().getY(), 5, 5); | ||
| } | ||
| } |
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,39 @@ | ||
| package game; | ||
|
|
||
| import gui.AbstractWindowState; | ||
|
|
||
| import java.awt.BorderLayout; | ||
|
|
||
| import javax.swing.JPanel; | ||
|
|
||
| public class GameWindow extends AbstractWindowState | ||
| { | ||
| private final GameVisualizer m_visualizer; | ||
| private final RobotLogic logic; | ||
| public GameWindow(String title, RobotLogic logic) | ||
| { | ||
| super(); | ||
|
|
||
| this.logic = logic; | ||
| logic.startTimer(); | ||
|
|
||
| setTitle(title); | ||
| setResizable(true); | ||
| setClosable(true); | ||
| setMaximizable(true); | ||
| setIconifiable(true); | ||
|
|
||
| m_visualizer = new GameVisualizer(logic); | ||
|
|
||
| JPanel panel = new JPanel(new BorderLayout()); | ||
| panel.add(m_visualizer, BorderLayout.CENTER); | ||
| getContentPane().add(panel); | ||
| pack(); | ||
| } | ||
|
|
||
| @Override | ||
| public void dispose() { | ||
| super.dispose(); | ||
| logic.stopTimer(); | ||
| } | ||
| } |
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,38 @@ | ||
| package game; | ||
|
|
||
| import java.awt.geom.Point2D; | ||
|
|
||
| public class Robot{ | ||
| private final Point2D.Double position = new Point2D.Double(100, 100); | ||
| private volatile double direction = 0; | ||
| private double angularVelocity = 0; | ||
| private final double velocity = 0.1; | ||
|
|
||
| public double getVelocity() { | ||
| return velocity; | ||
| } | ||
|
|
||
| public Point2D.Double getPosition() { | ||
| return position; | ||
| } | ||
|
|
||
| public double getDirection() { | ||
| return direction; | ||
| } | ||
|
|
||
| public void setDirection(double direction) { | ||
| this.direction = direction; | ||
| } | ||
|
|
||
| public void setAngularVelocity(double angularVelocity) { | ||
| this.angularVelocity = angularVelocity; | ||
| } | ||
|
|
||
| public double getAngularVelocity() { | ||
| return angularVelocity; | ||
| } | ||
|
|
||
| public void move(Point2D.Double dv) { | ||
| position.setLocation(getPosition().getX() + dv.getX(), getPosition().getY() + dv.getY()); | ||
| } | ||
| } |
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,34 @@ | ||
| package game; | ||
|
|
||
| import gui.AbstractWindowState; | ||
|
|
||
| import java.awt.*; | ||
| import java.util.Observable; | ||
| import java.util.Observer; | ||
| import javax.swing.JLabel; | ||
|
|
||
| public class RobotInfo extends AbstractWindowState implements Observer { | ||
| private final JLabel label; | ||
|
|
||
|
|
||
| public RobotInfo(RobotLogic logic) { | ||
| super(); | ||
| this.label = new JLabel(); | ||
|
|
||
| logic.addObserver(this); | ||
| setResizable(true); | ||
| setClosable(true); | ||
| setMaximizable(true); | ||
| setIconifiable(true); | ||
|
|
||
| getContentPane().add(label, BorderLayout.CENTER); | ||
| pack(); | ||
| } | ||
|
|
||
| @Override | ||
| public void update(Observable o, Object arg) { | ||
| RobotLogic lg = (RobotLogic) o; | ||
| label.setText("x=%f y=%f dir=%f".formatted(lg.getRobot().getPosition().getX(), | ||
| lg.getRobot().getPosition().getY(), lg.getRobot().getDirection())); | ||
| } | ||
| } |
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,125 @@ | ||
| package game; | ||
|
|
||
| import java.awt.geom.Point2D; | ||
| import java.awt.geom.Point2D.Double; | ||
| import java.util.Observable; | ||
| import java.util.Timer; | ||
| import java.util.TimerTask; | ||
|
|
||
| public class RobotLogic extends Observable { | ||
| private static final double ANGULAR_VELOCITY = 0.001; | ||
| private static final double TARGET_CLOSE_ENOUGH = 5; | ||
| private final static double EPSILON = 0.05; | ||
|
|
||
| private final Robot robot; | ||
| private Target target; | ||
|
|
||
| private final long dt = 5; | ||
| private Timer timer; | ||
| private Point2D.Double windowBounds = new Point2D.Double(300, 300); | ||
|
|
||
| public RobotLogic() { | ||
| robot = new Robot(); | ||
| target = new Target(10, 10); | ||
| setTarget(target); | ||
| moveRobot(); | ||
| } | ||
|
|
||
| public void startTimer() { | ||
| timer = new Timer("event generator", true); | ||
| addActionToTimer(new TimerTask() { | ||
| @Override | ||
| public void run() { | ||
| moveRobot(); | ||
|
|
||
| setChanged(); | ||
| notifyObservers(); | ||
| } | ||
| }, dt); | ||
| } | ||
|
|
||
| public void addActionToTimer(TimerTask task, long timeout) { | ||
| timer.schedule(task, 0, timeout); | ||
| } | ||
|
|
||
| public void stopTimer() { | ||
| timer.cancel(); | ||
| } | ||
|
|
||
| public Robot getRobot() { | ||
| return robot; | ||
| } | ||
|
|
||
| public Target getTarget() { | ||
| return target; | ||
| } | ||
|
|
||
| public void setTarget(Target target) { | ||
| this.target = target; | ||
|
|
||
| if (RobotsMath.angleTo(robot.getPosition(), target.getPosition()) > robot.getDirection()) { | ||
| robot.setAngularVelocity(-ANGULAR_VELOCITY); | ||
| } else { | ||
| robot.setAngularVelocity(ANGULAR_VELOCITY); | ||
| } | ||
| } | ||
|
|
||
| public void setWindowBounds(Point2D.Double windowBounds) { | ||
| this.windowBounds = windowBounds; | ||
| } | ||
|
|
||
| public void moveRobot() { | ||
| if (robot.getPosition().distance(target.getPosition()) < TARGET_CLOSE_ENOUGH) { | ||
| return; | ||
| } | ||
|
|
||
| final double angleRobotTarget = RobotsMath.angleTo(robot.getPosition(), target.getPosition()); | ||
|
|
||
| if (Math.abs(robot.getAngularVelocity()) < ANGULAR_VELOCITY || | ||
| Math.abs(robot.getDirection() - angleRobotTarget) < EPSILON) { | ||
| robot.move(new Double( | ||
| robot.getVelocity() * Math.cos(robot.getDirection()) * dt, | ||
| robot.getVelocity() * Math.sin(robot.getDirection()) * dt | ||
| )); | ||
|
|
||
| return; | ||
| } | ||
|
|
||
| final double newAngle = RobotsMath.asNormalizedRadians( | ||
| robot.getDirection() + robot.getAngularVelocity() * dt); | ||
|
|
||
| final double dx = robot.getVelocity() / robot.getAngularVelocity() * | ||
| (Math.sin(newAngle) - Math.sin(robot.getDirection())); | ||
| final double dy = robot.getVelocity() / robot.getAngularVelocity() * | ||
| (Math.cos(newAngle) - Math.cos(robot.getDirection())); | ||
|
|
||
| robot.move(new Point2D.Double( | ||
| dx * RobotsMath.speedCoefficient(robot.getPosition().getX(), windowBounds.getX()), | ||
| - dy * RobotsMath.speedCoefficient(robot.getPosition().getY(), windowBounds.getY()) | ||
| )); | ||
| robot.setDirection(newAngle); | ||
| } | ||
|
|
||
| private static class RobotsMath { | ||
| public static double angleTo(Point2D.Double p0, Point2D.Double p1) { | ||
| final double dx = p1.getX() - p0.getX(); | ||
| final double dy = p1.getY() - p0.getY(); | ||
|
|
||
| return asNormalizedRadians(Math.atan2(dy, dx)); | ||
| } | ||
|
|
||
| private static double asNormalizedRadians(double angle) { | ||
| final double TAU = 2 * Math.PI; | ||
|
|
||
| if (angle < 0) { | ||
| return TAU - ((-angle) % TAU); | ||
| } | ||
|
|
||
| return angle % TAU; | ||
| } | ||
|
|
||
| private static double speedCoefficient(double t, double upperBoundT) { | ||
| return Math.max(1 - 2 * Math.abs((upperBoundT - t) / upperBoundT - 0.5), 0.01); | ||
| } | ||
| } | ||
| } | ||
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 game; | ||
|
|
||
| import java.awt.geom.Point2D; | ||
|
|
||
| public class Target { | ||
| private final Point2D.Double position = new Point2D.Double(); | ||
|
|
||
| public Target(double x, double y) { | ||
| double rate = 3/2f; | ||
| position.setLocation(x * rate, y * rate); | ||
| } | ||
|
|
||
| public Point2D.Double getPosition() { | ||
| return position; | ||
| } | ||
| } |
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
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.
это просто Math