加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

C#实现的一个弹珠游戏

(2013-06-19 16:48:51)
标签:

c

弹珠

随机

picturebox

it

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace Marble
{
     public partial class Form1 : Form
     {
        public Form1()
        {
           InitializeComponent();
        }

     //delay for a while
     void sleep(int n)
     
        int i,j;
        for (i = 0; i < n; i++)
           for (j = 0; j < n; j++) ;
     }

     //When bump occures (either against the wall or against each other), the velocities are changed.
     void bump(int radius_1, int radius_2, int positionX_1, int positionY_1, int positionX_2, int positionY_2, ref double velocityX_1, ref double velocityY_1, ref double velocityX_2, ref double velocityY_2)
     {
        double tempVX_1 = 0.0, tempVY_1 = 0.0, tempVX_2 = 0.0, tempVY_2 = 0.0; //some temporary variables

        //bumping against the wall
        if (positionX_1 <= 0 + radius_1 || positionX_1 >= pictureBox1.Width - radius_1)
        velocityX_1 = -velocityX_1;
        if (positionY_1 <= 0 + radius_1 || positionY_1 >= pictureBox1.Height - radius_1)
        velocityY_1 = -velocityY_1;
        if (positionX_2 <= 0 + radius_2 || positionX_2 >= pictureBox1.Width - radius_2) 
        velocityX_2 = -velocityX_2;
        if (positionY_2 <= 0 + radius_2 || positionY_2 >= pictureBox1.Height - radius_2)
        velocityY_2 = -velocityY_2;

        double distance = Math.Sqrt((positionX_2 - positionX_1) * (positionX_2 - positionX_1) + (positionY_2 - positionY_1) * (positionY_2 - positionY_1));
        if (radius_1 + radius_2 >= distance)
        { //bumping against each other
           tempVX_1 = (2 * radius_2 * velocityX_2 + radius_1 * velocityX_1 - radius_2 * velocityX_1) / (radius_1 + radius_2);
           tempVY_1 = (2 * radius_2 * velocityY_2 + radius_1 * velocityY_1 - radius_2 * velocityY_1) / (radius_1 + radius_2);

           tempVX_2 = (2 * radius_1 * velocityX_1 + radius_2 * velocityX_2 - radius_1 * velocityX_2) / (radius_1 + radius_2);
           tempVY_2 = (2 * radius_1 * velocityY_1 + radius_2 * velocityY_2 - radius_1 * velocityY_2) / (radius_1 + radius_2);

           velocityX_1 = tempVX_1;
           velocityY_1 = tempVY_1;
           velocityX_2 = tempVX_2; 
           velocityY_2 = tempVY_2;
        }
     }

     //Draw the marble on the screem
     void drawMarble(Graphics g, Pen marble, SolidBrush brush, int center_x, int center_y, int radius)
     {
        g.DrawEllipse(marble, center_x - radius, center_y - radius, radius * 2, radius * 2);
        //Drawing a ellipse, with the position of top left corner, and diameter!
        g.FillEllipse(brush, center_x - radius, center_y - radius, radius * 2, radius * 2);
        //Filling a ellipse in the color of given brush
     }

     private void pictureBox1_Paint(object sender, PaintEventArgs e)
     {
        Random rnd = new Random(); //building a random object

        int radius_1 = rnd.Next(1, 81); //the radius of the 1st marble (representing mass). Value range: [1,80]
        int radius_2 = rnd.Next(1, 81); //the radius of the 2nd marble (representing mass). Value range: [1,80]
        //Althrough mass is in proportion to the cube of radius, here it's simple.

        int positionX_1 = rnd.Next(radius_1, pictureBox1.Width - radius_1 + 1); //the position of the center of circle in x-axis. Value range: all of the black screem
        int positionY_1 = rnd.Next(radius_1, pictureBox1.Height - radius_1 + 1); //the position of the center of circle in y-axis. Value range: all of the black screem
        int positionX_2 = rnd.Next(radius_2, pictureBox1.Width - radius_2 + 1); //the position of the center of circle in x-axis. Value range: all of the black screem
        int positionY_2 = rnd.Next(radius_2, pictureBox1.Height - radius_2 + 1); //the position of the center of circle in y-axis. Value range: all of the black screem
        //rnd.Next(a,b) returns a random int in [a,b)

        double distance = Math.Sqrt((positionX_2 - positionX_1) * (positionX_2 - positionX_1) + (positionY_2 - positionY_1) * (positionY_2 - positionY_1));

        while (radius_1 + radius_2 > distance)
        {
           //If the 2 marbles are too near, create the initial positions again.
           // //MessageBox.Show("The 2 marbles are too near!");
           // //Environment.Exit(0);
           positionX_1 = rnd.Next(radius_1, pictureBox1.Width - radius_1 + 1); //the position of the center of circle in x-axis. Value range: all of the black screem
           positionY_1 = rnd.Next(radius_1, pictureBox1.Height - radius_1 + 1); //the position of the center of circle in y-axis. Value range: all of the black screem
           positionX_2 = rnd.Next(radius_2, pictureBox1.Width - radius_2 + 1); //the position of the center of circle in x-axis. Value range: all of the black screem
           positionY_2 = rnd.Next(radius_2, pictureBox1.Height - radius_2 + 1); //the position of the center of circle in y-axis. Value range: all of the black screem
           }

           double velocityX_1 = 20 * rnd.NextDouble() - 10; //The initial velocities of marbles. Value range: [-10.0,10.0)
           double velocityY_1 = 20 * rnd.NextDouble() - 10;
           double velocityX_2 = 20 * rnd.NextDouble() - 10;
           double velocityY_2 = 20 * rnd.NextDouble() - 10;
//rnd.NextDouble() returns a random double in [0.0,1.0)

           Graphics g = pictureBox1.CreateGraphics();
           Pen marble_1 = new Pen(Color.Red, 1); //Create a Pen 
           Pen marble_2 = new Pen(Color.Blue, 1);
           SolidBrush brush_1 = new SolidBrush(Color.Red); //Create a brush which used to fill the marbel in a color
           SolidBrush brush_2 = new SolidBrush(Color.Blue);

           pictureBox1.BackColor = Color.Black; //set the back color of screem as black

           //while(true)
           for (int i = 0; i < 3000; i++)
           {
              g.Clear(pictureBox1.BackColor);
              drawMarble(g, marble_1, brush_1, positionX_1, positionY_1, radius_1);
              drawMarble(g, marble_2, brush_2, positionX_2, positionY_2, radius_2);

              positionX_1 += Convert.ToInt32(velocityX_1);
              positionY_1 += Convert.ToInt32(velocityY_1);
              positionX_2 += Convert.ToInt32(velocityX_2);
              positionY_2 += Convert.ToInt32(velocityY_2);

              bump(radius_1, radius_2, positionX_1, positionY_1, positionX_2, positionY_2, ref velocityX_1, ref velocityY_1, ref velocityX_2, ref velocityY_2);

              sleep(3000);
           }
        }
     }
}

0

阅读 收藏 喜欢 打印举报/Report
前一篇:柏林马拉松
后一篇:北欧一年纪
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有