Загрузка данных


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Runtime.CompilerServices;

namespace ArkanoidGame
{
    public partial class Form1 : Form
    {

        int ballX = 300;
        int ballY = 300;
        int dx = 8;
        int dy = -8;

        int paddleX = 400;
        int paddleY = 600;
        int paddleWidth = 120;
        int paddleHeight = 15;

        int score = 0;
        int lives = 3;

        int ballSize = 20;

        bool gameStarted = false;
        bool paused = false;
        int currentLevel;
        int reachedLevel = 1;



        List<Rectangle> bricks = new List<Rectangle>();
        public Form1(int level)
        {
            InitializeComponent();

            currentLevel = level;
            timer1.Interval = 16; // 16 мс для ~60 FPS
            timer1.Tick += timer1_Tick;

            this.DoubleBuffered = true;
            currentLevel = level;
            CreateLevel(level);

            // Уберем лишний вызов Start(), так как таймер уже включен в InitializeComponent()
            timer1.Start(); 

            btnResume.Visible = false;
            btnRestart.Visible = false;
            btnMenu.Visible = false;

            this.MouseMove += Form1_MouseMove;

            // --- ИСПРАВЛЕНИЕ ---
            // Не начинаем игру сразу. Ставим мяч на платформу и ставим игру на паузу.
            gameStarted = false;
            ResetBall();
            // -------------------


            if (gameStarted && bricks.Count == 0)
            {
                timer1.Stop();
                gameStarted = false;

                MessageBox.Show("You Win!");
            }

            gameStarted = false;
            ResetBall();
        }








        private void Form1_Load(object sender, EventArgs e)
        {

        }

        protected override void OnPaint(PaintEventArgs e)
        {
            Graphics g = e.Graphics;

            // мяч
            g.FillEllipse(Brushes.White, ballX, ballY, ballSize, ballSize);

            // платформа
            g.FillRectangle(Brushes.Blue, paddleX, paddleY, paddleWidth, paddleHeight);

            // UI
            g.DrawString("Score: " + score, Font, Brushes.White, 10, 10);
            g.DrawString("Lives: " + lives, Font, Brushes.White, 10, 30);

            foreach (var b in bricks)
            {
                g.FillRectangle(Brushes.OrangeRed, b);
                g.DrawRectangle(Pens.Black, b);
            }

            if (paused)
            {
                e.Graphics.FillRectangle(
                    new SolidBrush(Color.FromArgb(150, Color.Black)),
                    ClientRectangle
                    );

                e.Graphics.DrawString(
                    "PAUSED",
                    new Font("Arial", 40),
                    Brushes.White,
                    300,
                    200
                    );
            }

            try
            {
                string imagePath = @"C:\Users\PC\Pictures\P.jpg";
                this.BackgroundImage = Image.FromFile(imagePath);
                this.BackgroundImageLayout = ImageLayout.Stretch;
            }
            catch (Exception ex)
            {

            }

            this.StartPosition = FormStartPosition.CenterScreen;
            this.ClientSize = new Size(850, 700);
            this.Text = "Форма с изображением из файла";

        
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (!gameStarted || paused)
                return;

            ballX += dx;
            ballY += dy;

            // Отскок от боковых стен и потолка
            if (ballX < 0 || ballX + ballSize > ClientSize.Width)
                dx *= -1;

            if (ballY < 0)
                dy *= -1;

            Rectangle ballRect = new Rectangle(ballX, ballY, ballSize, ballSize);

            // Отскок от платформы с эффектом угла
            Rectangle paddleRect = new Rectangle(paddleX, paddleY, paddleWidth, paddleHeight);

            if (ballRect.IntersectsWith(paddleRect))
            {
                dy *= -1;

                // Угол отскока зависит от точки удара по платформе
                double relativeIntersectX = (paddleX + (paddleWidth / 2)) - ballX;
                double normalizedIntersect = relativeIntersectX / (paddleWidth / 2);

                double bounceAngle = normalizedIntersect * (5 * Math.PI / 12); // ~75 градусов в сумме

                dx = (int)(-8 * Math.Sin(bounceAngle));
                dy = (int)(-8 * Math.Cos(bounceAngle));

                // Убедимся, что мяч не застрял в платформе
                while (ballRect.IntersectsWith(paddleRect))
                {
                    ballY -= dy / 2;
                    ballRect.Y = ballY;
                }
            }

            // Проверка столкновений с кирпичами
            for (int i = bricks.Count - 1; i >= 0; i--)
            {
                if (bricks[i].IntersectsWith(ballRect))
                {
                    bricks.RemoveAt(i);
                    score += 10;

                    // Простая логика отскока: если мяч движется горизонтально к кирпичу - меняем dx,
                    // если вертикально - меняем dy.
                    bool movingLeft = dx < 0;
                    bool movingRight = dx > 0;

                    bool brickLeft = bricks[i].Right <= ballRect.Left && bricks[i].Right > ballRect.Left - Math.Abs(dx);
                    bool brickRight = bricks[i].Left >= ballRect.Right && bricks[i].Left < ballRect.Right + Math.Abs(dx);

                    if ((movingLeft && brickLeft) || (movingRight && brickRight))
                        dx *= -1;

                    bool movingUp = dy < 0;

                    bool brickTop = bricks[i].Bottom <= ballRect.Top && bricks[i].Bottom > ballRect.Top - Math.Abs(dy);

                    if ((movingUp && brickTop) || (!movingUp && bricks[i].Top >= ballRect.Bottom))
                        dy *= -1;

                    IncreaseSpeed();

                    break; // Удаляем только один кирпич за тик для стабильности физики
                }
            }

            // Проверка проигрыша (мяч ушел за нижнюю границу)
            if (ballY > ClientSize.Height + ballSize)
            {
                lives--;

                if (lives <= 0)
                {
                    timer1.Stop();
                    MessageBox.Show("Game Over! \nYour score: " + score);
                    SaveScore();
                    this.Close();
                }
                else
                {
                    ResetBall();
                }
            }

            Invalidate();
        }


        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            if (keyData == Keys.Escape)
            {
                paused = !paused;
                timer1.Enabled = !paused;

                btnResume.Visible = true;
                btnRestart.Visible = true;
                btnMenu.Visible = true;

                btnResume.Enabled = true;
                btnRestart.Enabled = true;
                btnMenu.Enabled = true;

                btnResume.BringToFront();
                btnRestart.BringToFront();
                btnMenu.BringToFront();

            }

            return base.ProcessCmdKey(ref msg, keyData);
        }

        private void Form1_MouseMove(object sender, MouseEventArgs e)
        {
            paddleX = e.X - paddleWidth / 2;
        }


        private void CreateLevel(int level)
        {
            bricks.Clear();

            switch (level)
            {
                case 1:
                    SimpleLevel();
                    break;

                case 2:
                    PyramidLevel();
                    break;

                case 3:
                    WallsLevel();
                    break;

                case 4:
                    CheckerLevel();
                    break;

                case 5:
                    HardLevel();
                    break;

                case 6:
                    CrossLevel();
                    break;

                case 7:
                    RandomLevel();
                    break;
            }
        }

        void SimpleLevel()
        {
            for (int i = 0; i < 4; i++)
                for (int j = 0; j < 8; j++)
                    bricks.Add(new Rectangle(100 + j * 80, 50 + i * 30, 70, 20));
        }

        void PyramidLevel()
        {
            for (int i = 0; i < 5; i++)
                for (int j = 0; j <= i; j++)
                    bricks.Add(new Rectangle(300 + j * 80 - i * 40, 50 + i * 30, 70, 20));
        }

        void IncreaseSpeed()
        {
                dx += Math.Sign(dx);
                dy += Math.Sign(dy);

                dx = Math.Max(Math.Min(dx, 12), -12);
                dy = Math.Max(Math.Min(dy, 12), -12);

        }

        void WallsLevel()
        {
            for (int i = 0; i < 6; i++)
            {
                bricks.Add(new Rectangle(100, 50 + i * 30, 70, 20));
                bricks.Add(new Rectangle(700, 50 + i * 30, 70, 20));
            }
        }

        void CheckerLevel()
        {
            for (int i = 0; i < 6; i++)
                for (int j = 0; j < 10; j++)
                    if ((i + j) % 2 == 0)
                        bricks.Add(new Rectangle(100 + j * 70, 50 + i * 30, 65, 20));
        }

        void HardLevel()
        {
            for (int i = 0; i < 7; i++)
                for (int j = 0; j < 10; j++)
                    bricks.Add(new Rectangle(80 + j * 75, 40 + i * 25, 70, 20));
        }

        void CrossLevel()
        {
            for (int i = 0; i < 7; i++)
            {
                bricks.Add(new Rectangle(400, 50 + i * 30, 70, 20));
                bricks.Add(new Rectangle(200 + i * 70, 200, 70, 20));
            }
        }

        void RandomLevel()
        {
            Random rnd = new Random();

            for (int i = 0; i < 30; i++)
            {
                int x = rnd.Next(50, 700);
                int y = rnd.Next(50, 300);

                bricks.Add(new Rectangle(x, y, 70, 20));
            }
        }

        void SaveScore()
        {
            string line = UserSession.Username + ";" + reachedLevel;
            File.AppendAllText("scores.txt", line + Environment.NewLine);
        }

        private void btnResume_Click(object sender, EventArgs e)
        {
            paused = false;

            btnResume.Visible = false;
            btnRestart.Visible = false;
            btnMenu.Visible = false;

            timer1.Start();
        }

        void ResetBall()
        {
            ballX = paddleX + paddleWidth / 2 - ballSize / 2; // По центру платформы
            ballY = paddleY - ballSize; // Чуть выше платформы

            // Небольшая пауза перед запуском, чтобы игрок успел подготовиться
            paused = true;

            // Используем Task.Delay для асинхронной паузы, чтобы не блокировать UI поток
            Task.Delay(1500).ContinueWith(t => { paused = false; });
        }

        private void btnRestart_Click(object sender, EventArgs e)
        {
            lives = 3;
            score = 0;

            CreateLevel(currentLevel);

            ballX = 300;
            ballY = 300;
            dx = 5;
            dy = -5;

            paused = false;
            btnResume.Visible = false;
            btnRestart.Visible = false;
            btnMenu.Visible = false;

            timer1.Start();
        }

        private void btnMenu_Click(object sender, EventArgs e)
        {
            MainMenuForm menu = new MainMenuForm();
            menu.Show();

            this.Close();
        }
    }
}