cscの作法 その467

# 概要
cscの作法、調べてみた。
練習問題やってみた。

# 練習問題
ブロック崩しに、音を付けよ。

# 方針
- beep使う。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/2d273a14-f1d8-b0f6-1c28-6087429bd633.png)


# サンプルコード

```
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Windows;
using System.Windows.Forms;

namespace Breakout
{
	public partial class Form1: Form {
		Label label1;
		Label label2;
		Vector ballPos;
		Vector ballSpeed;
		int ballRadius;
		Rectangle paddlePos;
		List<Rectangle> blockPos;
		Timer timer = new Timer();
		Timer timerCount = new Timer();
		int countSize = 200;
		int countNo = 3;
		double accelSpeed = 1;
		public static int blockNum {
			get;
			set;
		}
		public static int blockNumMax {
			get;
			set;
		}
		public static Stopwatch keikaTime = new Stopwatch();
		public Form1() {
			Text = "Breakout";
			ClientSize = new System.Drawing.Size(600, 400);
			label1 = new Label();
			label1.Location = new System.Drawing.Point(550, 50);
			label1.Text = "test1";
			Controls.AddRange(new Control[] {
				label1
			});
			label2 = new Label();
			label2.Location = new System.Drawing.Point(550, 150);
			label2.Text = "test2";
			Controls.AddRange(new Control[] {
				label2
			});
			this.ballSpeed = new Vector(3, 3);
			this.ballPos = new Vector(200, 200);
			this.ballRadius = 10;
			this.paddlePos = new Rectangle(100, this.Height - 50, 100, 5);
			this.blockPos = new List<Rectangle>();
			blockNum = 0;
			for (int x = 0; x <= this.Height; x += 100)
			{
				for (int y = 0; y <= 150; y += 40)
				{
					this.blockPos.Add(new Rectangle(25 + x, y, 80, 25));
					blockNum++;
				}
			}
			blockNumMax = blockNum;
			label1.BackColor = Color.Transparent;
			label2.BackColor = Color.Transparent;
			this.KeyDown += new KeyEventHandler(Form1_KeyDown);
			timer.Interval = 80;
			timerCount.Tick += new EventHandler(countDown);
			timerCount.Start();
		}
		private void countDown(object sender, EventArgs e) {
			if (countSize == 0)
			{
				countNo--;
				label1.Text = countNo.ToString();
				countSize = 200;
			}
			if (countSize == 20 && countNo == 1)
			{
				timerCount.Stop();
				countDownAfter();
			}
			countSize -= 20;
		}
		private void countDownAfter() {
			timer.Interval = 70;
			timer.Tick += new EventHandler(Update);
			timer.Start();
			keikaTime.Start();
		}
		private void realTime() {
			label2.Text = keikaTime.Elapsed.ToString().Substring(6, 6);
		}
		double DotProduct(Vector a, Vector b) {
			return a.X * b.X + a.Y * b.Y;
		}
		bool LineVsCircle(Vector p1, Vector p2, Vector center, float radius) {
			Vector lineDir = (p2 - p1);
			Vector n = new Vector(lineDir.Y, -lineDir.X);
			n.Normalize();
			Vector dir1 = center - p1;
			Vector dir2 = center - p2;
			double dist = Math.Abs(DotProduct(dir1, n));
			double a1 = DotProduct(dir1, lineDir);
			double a2 = DotProduct(dir2, lineDir);
			return (a1 * a2 < 0 && dist < radius) ? true : false;
		}
		int BlockVsCircle(Rectangle block, Vector ball) {
			if (LineVsCircle(new Vector(block.Left, block.Top), new Vector(block.Right, block.Top), ball, ballRadius))
				return 1;
			if (LineVsCircle(new Vector(block.Left, block.Bottom), new Vector(block.Right, block.Bottom), ball, ballRadius))
				return 2;
			if (LineVsCircle(new Vector(block.Right, block.Top), new Vector(block.Right, block.Bottom), ball, ballRadius))
				return 3;
			if (LineVsCircle(new Vector(block.Left, block.Top), new Vector(block.Left, block.Bottom), ball, ballRadius))
				return 4;
			return -1;
		}
		private void Update(object sender, EventArgs e) {
			realTime();
			int x = 1;
			if (x / 100 == 1)
			{
				ballSpeed.X *= accelSpeed;
				ballSpeed.Y *= accelSpeed;
				ballPos += ballSpeed;
				accelSpeed += 0.001;
			}
			else
			{
				ballPos += ballSpeed;
			}
			if (ballPos.X + ballRadius * 3 > this.Bounds.Width || ballPos.X - ballRadius < 0)
			{
				ballSpeed.X *= -1;
				Console.Beep(500, 200);
			}
			if (ballPos.Y - ballRadius < 0)
			{
				ballSpeed.Y *= -1;
				Console.Beep(500, 200);
			}
			if (LineVsCircle(new Vector(this.paddlePos.Left, this.paddlePos.Top), new Vector(this.paddlePos.Right, this.paddlePos.Top), ballPos, ballRadius))
			{
				if (ballPos.Y + 20 > paddlePos.Top)
				{
					ballSpeed.Y *= -1;
					Console.Beep(500, 200);
				}
			}
			for (int i = 0; i < this.blockPos.Count; i++)
			{
				int collision = BlockVsCircle(blockPos[i], ballPos);
				if (collision == 1 || collision == 2)
				{
					ballSpeed.Y *= -1;
					Console.Beep(500, 200);
					this.blockPos.Remove(blockPos[i]);
					blockNum--;
				}
				else if (collision == 3 || collision == 4)
				{
					ballSpeed.X *= -1;
					Console.Beep(500, 200);
					this.blockPos.Remove(blockPos[i]);
					blockNum--;
				}
			}
			if (ballPos.Y > this.Height || blockNum == 0)
			{
				keikaTime.Stop();
				timer.Stop();
				MessageBox.Show("game over !!");
				Application.Exit();
			}
			Invalidate();
		}
		protected override void OnPaint(PaintEventArgs e) {
			SolidBrush pinkBrush = new SolidBrush(Color.HotPink);
			SolidBrush grayBrush = new SolidBrush(Color.DimGray);
			SolidBrush blueBrush = new SolidBrush(Color.LightBlue);
			float px = (float) this.ballPos.X - ballRadius;
			float py = (float) this.ballPos.Y - ballRadius;
			e.Graphics.FillEllipse(pinkBrush, px, py, this.ballRadius * 2, this.ballRadius * 2);
			e.Graphics.FillRectangle(grayBrush, paddlePos);
			for (int i = 0; i < this.blockPos.Count; i++)
			{
				e.Graphics.FillRectangle(blueBrush, blockPos[i]);
			}
		}
		private void Form1_KeyDown(object sender, KeyEventArgs e) {
			switch(e.KeyData)
			{
			case Keys.Left:
				this.paddlePos.X -= 20;
			break;
			case Keys.Right:
				this.paddlePos.X += 20;
			break;
			default:
			break;
			}
		}
		private void form1_Closing(object sender, FormClosingEventArgs e) {
			keikaTime.Stop();
			timer.Stop();
			timerCount.Stop();
			this.Close();
			this.Hide();
		}
		[STAThread]
		static void Main(string[] args) {
			Application.Run(new Form1());
		}
	}
}





```

以上。