Open tsuikit159 opened 10 months ago
I have changed a bit to enable the player movement bounded due to the sun's gravity.
However, some of the previous functions like splitting the player do not work.
Do you guys think of a way to fix this?
MainWindow.xaml.cs
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
using System.Threading.Tasks;
using Circle;
namespace Project
{
///
public static bool CheckCollision(Orb e1, Orb e2)
{
var r1 = e1.Size / 2;
var x1 = e1.Position.X + r1;
var y1 = e1.Position.Y + r1;
var r2 = e2.Size / 2;
var x2 = e2.Position.X + r2;
var y2 = e2.Position.Y + r2;
var d = new Vector(x2 - x1, y2 - y1);
return d.Length <= r1 + r2;
}
public MainWindow()
{
InitializeComponent();
/// initzialize the canvas
///
canvas = new Canvas();
playerPosition = new Point(100, 640);
sunPosition = new Point(400, 640);
sun = new Orb(1280, 800, sunSize, Colors.Yellow);
player = new Orb(1280, 800, playerSize, Colors.Blue);
playerVelocity = new Vector(0, 0);
enemies = new List<Orb>();
Window.AddHandler(PreviewMouseLeftButtonDownEvent, new MouseButtonEventHandler(MouseDown), true);
Window.AddHandler(PreviewMouseLeftButtonUpEvent, new MouseButtonEventHandler(MouseUp), true);
timer.Interval = TimeSpan.FromMilliseconds(16);
timer.Tick += GameTick;
timer.Start();
}
private void GameTick(object sender, EventArgs e)
{
UpdatePlayerPosition();
DrawGameObjects();
collide();
if (MousePressed == true)
{ // get the mouse position
tickcount ++;
float speed = 0.2f;
double centerX = mouseEventArgs.GetPosition(GameScreen).X;
double centerY = mouseEventArgs.GetPosition(GameScreen).Y;
// get the player position
double playerX = playerPosition.X;
double playerY = playerPosition.Y;
// get the angle between the mouse and the player
double dx = centerX - playerX;
double dy = centerY - playerY;
double angle = Math.Atan2(dy, dx);
double oppositeAngle = angle + Math.PI;
// move the player to the opposite side
double oppositeX = (playerX + Math.Cos(oppositeAngle));
double oppositeY = (playerY + Math.Sin(oppositeAngle));
// set the player position in the canvas
playerPosition.X = oppositeX;
playerPosition.Y = oppositeY;
DrawOrb(playerPosition, player.Size, player.Color);
if (tickcount > 8)
{
tickcount = 0;
// Code to execute when the gametimer reaches 500 milliseconds
IShapeFactory factory = new CircleFactory((playerSize)/4);
Shape circle = factory.CreateShape();
Ellipse checkellipse = circle as Ellipse;
// Move the circle to the opposite of the player side
double circleX = (playerPosition.X - Math.Cos(oppositeAngle) - (player.Size / 4) *2);
double circleY = (playerPosition.Y - Math.Sin(oppositeAngle) - (player.Size / 4) * 2 );
/*
foreach (var x in GameScreen.Children.OfType<Ellipse>().ToList())
{
if (CheckCollision(checkellipse,x))
{
if (player.Size > x.Width)
{
GameScreen.Children.Remove(x);
circle.Width += 2;
circle.Height += 2;
}
else
{
GameScreen.Children.Remove(circle);
x.Width += 2;
x.Height += 2;
}
}
}
*/
Canvas.SetLeft(circle, circleX);
Canvas.SetTop(circle, circleY);
GameScreen.Children.Add(circle);
}
}
}
private void MouseDown(object sender, MouseButtonEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
MousePressed = true;
mouseEventArgs = e;
MouseMove += (sender, e) => mousePosition = e.GetPosition(GameScreen);
// set the circle position in the canvas
}
}
public void MouseUp(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left)
{
MousePressed = false;
Console.WriteLine("mouse released");
}
}
public void collide()
{
foreach (var x in GameScreen.Children.OfType<Ellipse>().ToList())
{
foreach(var enemy in enemies)
{
if ((string)x.Tag == "circle")
{
if (CheckCollision(player, enemy))
{
if (player.Size > x.Width)
{
GameScreen.Children.Remove(x);
player.Size += player.Size / 10;
}
else
{
MessageBox.Show("Game Over");
this.Close();
}
}
else if (CheckCollision(sun, enemy))
{
GameScreen.Children.Remove(x);
sun.Size += 2;
}
}
else if (CheckCollision(player, sun))
{
MessageBox.Show("Game Over");
this.Close();
}
}
}
}
private void UpdatePlayerPosition()
{
playerVelocity += (sunPosition - playerPosition) * 0.0001;
playerPosition += playerVelocity;
playerPosition = ClampPosition(playerPosition);
}
private Point ClampPosition(Point position)
{
double x = Math.Max(0, Math.Min(1280, position.X));
double y = Math.Max(0, Math.Min(800, position.Y));
return new Point(x, y);
}
private void DrawGameObjects()
{
GameScreen.Children.Clear();
DrawOrb(playerPosition, player.Size, Colors.Blue);
DrawOrb(sunPosition, sun.Size, Colors.Yellow);
foreach (var enemy in enemies)
{
DrawOrb(enemy.Position, enemy.Size, enemy.Color);
}
}
private void DrawOrb(Point position, double size, Color color)
{
var ellipse = new Ellipse
{
Width = size,
Height = size,
Fill = new SolidColorBrush(color)
};
Canvas.SetLeft(ellipse, position.X - size / 2);
Canvas.SetTop(ellipse, position.Y - size / 2);
GameScreen.Children.Add(ellipse);
}
}
public class Orb
{
public Point Position { get; set; }
public Vector Velocity { get; set; }
public double Size { get; set; }
public Color Color { get; set; }
public Orb(double x, double y, double size, Color color, Vector velocity = default)
{
Position = new Point(x, y);
Size = size;
Color = color;
Velocity = velocity;
}
public bool Contains(Point point, double radius)
{
return (Position - point).Length <= (Size / 2 + radius / 2);
}
public void AccelerateTowards(Point target)
{
var acceleration = (target - Position) * 0.001;
Velocity += acceleration;
}
public void UpdatePosition()
{
Position += Velocity;
}
}
}
what do you mean by splitting the player? you can commit your progress to the dev branch so I can see what happened in your case
I have just put the codes inside the gravitational-force branch. You can check it out.
i just put some adjustment into the code, but is not totally work.
private void UpdatePosition()
{
double angle = Math.Atan2(Canvas.GetTop(Sun) - Canvas.GetTop(Player), Canvas.GetLeft(Sun) - Canvas.GetLeft(Player));
foreach (var x in GameScreen.Children.OfType
double Gangle = Math.Atan2(Canvas.GetTop(Sun) - Canvas.GetTop(Player), Canvas.GetLeft(Sun) - Canvas.GetLeft(Player));
double dx = Canvas.GetLeft(Sun) - Canvas.GetLeft(Player);
double dy = Canvas.GetTop(Sun) - Canvas.GetTop(Player);
double distance = Math.Sqrt(Math.Pow(dx, 2) + Math.Pow(dy, 2));
// Calculate the acceleration
// Update the speed
// Set the position of the player and the circle
Canvas.SetLeft(x, Canvas.GetLeft(x) + speedx);
Canvas.SetTop(x, Canvas.GetTop(x) + speedy);
}
for (int i = 0; i < GameScreen.Children.Count; i++)
{
if (GameScreen.Children[i] is Ellipse circle && (string)circle.Tag == "circle")
{
double dx = Canvas.GetLeft(Sun) - Canvas.GetLeft(circle);
double dy = Canvas.GetTop(Sun) - Canvas.GetTop(circle);
double distance = Math.Sqrt(Math.Pow(dx, 2) + Math.Pow(dy, 2));
double force = G * (Player.Width * circle.Width) / Math.Pow(distance, 2);
double acceleration = force / (Player.Width * circle.Width);
double velocity = Math.Sqrt(acceleration * distance);
double velocityX = velocity * Math.Cos((double)Math.Atan2(dy, dx));
double velocityY = velocity * Math.Sin((double)Math.Atan2(dy, dx));
double newX = Canvas.GetLeft(circle) + velocityX;
double newY = Canvas.GetTop(circle) + velocityY;
if (distance > range)
{
double PlayerX = Canvas.GetLeft(Player) + velocityX;
double PlayerY = Canvas.GetTop(Player) + velocityY;
Canvas.SetLeft(Player, PlayerX);
Canvas.SetTop(Player, PlayerY);
}
else
{
double PlayerX = Canvas.GetLeft(Player) -velocityX;
double PlayerY = Canvas.GetTop(Player) - velocityY;
Canvas.SetLeft(Player, PlayerX);
Canvas.SetTop(Player, PlayerY);
}
Canvas.SetLeft(circle, newX);
Canvas.SetTop(circle, newY);
}
}
}
TODO: Follow the physics rule as the instructions have mentioned,
The instructions state that you might include Newton's Mechanic, but it seems optional to do that.