public override bool PerformFrame(BCBlockGameState gamestate) { //hitscan. We only "take" a single frame to hit something. //first, normalize the Velocity. _Velocity = _Velocity.Normalize(); //now, starting from _Origin, advance position by _Velocity until we hit a block or leave the gamearea. List<Block> blockshit = new List<Block>(); PointF currpos = _Origin; PointF lastpos = _Origin; bool scancomplete = false; int spawnjump = 0; int particlecomparator = Math.Max(gamestate.Particles.Count-500, 2); //particlecomparator is our modulus. This will be modulo'd with spawnjump each iteration while (!scancomplete) { spawnjump++; currpos = new PointF(currpos.X + _Velocity.X, currpos.Y + _Velocity.Y); PointF diff = new PointF(currpos.X-lastpos.X,currpos.Y-lastpos.Y); //spawn some particles here. if (spawnjump>particlecomparator && Tracer) { spawnjump = 0; for (int i = 0; i < 1; i++) { float randomspot = (float)BCBlockGameState.rgen.NextDouble(); PointF randomoffset = new PointF(currpos.X + diff.X * randomspot, currpos.Y + diff.Y * randomspot); if (BCBlockGameState.rgen.NextDouble() > 0.5) { DustParticle dp = new DustParticle(randomoffset, 3, 25, _BulletColor); dp.Important = true; gamestate.Particles.Add(dp); } else { LightOrb dp = new LightOrb(randomoffset, Color.Green, 16); dp.TTL = 25; dp.Important = true; gamestate.Particles.Add(dp); } } } //are we outside gamearea? if (!gamestate.GameArea.Contains(currpos.ToPoint())) scancomplete = true; //have we hit a block? var hitblock = BCBlockGameState.Block_HitTestOne(gamestate.Blocks, currpos); if (hitblock != null && !blockshit.Contains(hitblock)) { blockshit.Add(hitblock); if(_Strength == HitscanStrengthConstants.hitscan_bullet) { //create a bullet at currpos, make it go in our direction. Bullet bb = new Bullet(currpos, _Velocity, false); bb.BulletBrush = new SolidBrush(Color.Transparent); //invisible bullet... gamestate.NextFrameCalls.Enqueue(new BCBlockGameState.NextFrameStartup(() => gamestate.GameObjects.AddLast(bb))); } else if(_Strength==HitscanStrengthConstants.hitscan_hit) { gamestate.NextFrameCalls.Enqueue(new BCBlockGameState.NextFrameStartup(() => BCBlockGameState.Block_Hit(gamestate, hitblock, _Velocity))); } if (!Penetrate) scancomplete = true; } lastpos = currpos; } if (!Tracer) { DustParticle pa = new DustParticle(Origin, 800,9000,Color.Transparent); DustParticle pb = new DustParticle(currpos,800,9000,Color.Transparent); pa.Velocity = PointF.Empty; pb.Velocity = PointF.Empty; LineParticle ls = new LineParticle(pa, pb,new Pen(Color.Yellow,1)); ls.Important = true; ls.TTL = 750; gamestate.Particles.Add(ls); //show the impact point. PointF Impactpoint = currpos; for (int i = 0; i < 14 * BCBlockGameState.Settings.ParticleGenerationFactor; i++) { Particle xp = BCBlockGameState.rgen.NextDouble() > 0.5 ? (Particle) new EmitterParticle(Impactpoint,(gstate,emitter,aint,bint)=> { float ssspeed = (float)BCBlockGameState.rgen.NextDouble() * 5 + 2; PointF ssusespeed = BCBlockGameState.VaryVelocity(new PointF(0,-ssspeed), Math.PI / 10); DustParticle addit = new DustParticle(emitter.Location, 40); addit.Velocity = ssusespeed; return addit; }) : (Particle)new DustParticle(Impactpoint); float speed = (float)BCBlockGameState.rgen.NextDouble() * 5 + 2; PointF usespeed = BCBlockGameState.VaryVelocity(new PointF(0,-speed), Math.PI / 10); xp.Velocity = usespeed; gamestate.Particles.Add(xp); } } return true; //we only exist for one frame. }
public Point Move(IField field) { var velocity = 0f; lock(velocityLock) velocity = Velocity; var location = new PointF(Location.X, Location.Y); velocity *= field.Time.TimeStep / field.Time.Interval; var vecV = Direction.Multiply(velocity); var step = field.Time.TimeStep; var endTime = field.Time.Interval + field.Time.TimeStep; var rectangles = field.StaticObjBoundaries; for (var time = 0f; time < endTime; time += step) { location = location.Add(vecV); var curLocRect = new RectangleF(location, Size); foreach (var rect in rectangles) if (curLocRect.IntersectsWith(rect)) { var intersectRect = RectangleF.Intersect(curLocRect, rect);//.Location; var normal = GetNormal(intersectRect, rect); var negDir = Direction.Negate(); Direction = negDir.Reflect(location, normal).Normalize(); vecV = Direction.Multiply(velocity); location = location.Add(vecV); curLocRect = new RectangleF(location, Size); while (curLocRect.IntersectsWith(rect)) { location = location.Add(vecV); curLocRect = new RectangleF(location, Size); } break; } } return location.ToPoint(); }
private unsafe void ProcessImage(ref Image<Bgr, byte> img) { Image<Gray, byte> gray_image = img.Convert<Gray, byte>(); grayImg = gray_image; binaryImg = gray_image.ThresholdBinaryInv(new Gray(200), new Gray(255)); //Find contours with no holes try CV_RETR_EXTERNAL to find holes IntPtr Dyncontour = new IntPtr();//存放检测到的图像块的首地址 IntPtr Dynstorage = CvInvoke.cvCreateMemStorage(0); int n = CvInvoke.cvFindContours(binaryImg.Ptr, Dynstorage, ref Dyncontour, sizeof(MCvContour), Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_TREE, Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, new Point(0, 0)); Seq<Point> DyncontourTemp1 = new Seq<Point>(Dyncontour, null);//方便对IntPtr类型进行操作 Seq<Point> DyncontourTemp = DyncontourTemp1; List<MCvBox2D> rectList = new List<MCvBox2D>(); for (; DyncontourTemp != null && DyncontourTemp.Ptr.ToInt32() != 0; DyncontourTemp = DyncontourTemp.HNext) { CvInvoke.cvDrawContours(image, DyncontourTemp, new MCvScalar(255, 0, 0), new MCvScalar(0, 255, 0), 10, 1, Emgu.CV.CvEnum.LINE_TYPE.FOUR_CONNECTED, new Point(0, 0)); PointF[] rect1 = DyncontourTemp.GetMinAreaRect().GetVertices(); rectList.Add(DyncontourTemp.GetMinAreaRect()); var pointfSeq = from p in rect1 select new Point((int)p.X, (int)p.Y); Point[] points = pointfSeq.ToArray(); for (int j = 0; j < 4; j++) { CvInvoke.cvLine(image, points[j], points[(j + 1) % 4], new MCvScalar(0, 0, 255), 1, Emgu.CV.CvEnum.LINE_TYPE.EIGHT_CONNECTED, 0); } //CvInvoke.cvNamedWindow("main"); } for (int i = 0; i < rectList.Count(); i++) { MCvBox2D rect = rectList[i]; PointF[] pl = rect.GetVertices(); var points = from p in pl orderby p.Y ascending select p; pl = points.ToArray(); PointF startP = pl[0]; PointF shortP = pl[1]; PointF longP = pl[2]; if (pl[1].DistanceTo(startP) > pl[2].DistanceTo(startP)) { shortP = pl[2]; longP = pl[1]; } float longDis = longP.DistanceTo(startP); if (longDis < minLength) { continue; } float shortDis = shortP.DistanceTo(startP); float longslope = Math.Abs(longP.X - startP.X) / longDis; float min = 9999; PointF ap1 = new PointF(); PointF ap2 = new PointF(); if (longslope < 0.707)//vert { for (int y = begin; y < Convert.ToInt32(Math.Abs(longP.Y - startP.Y)) && Math.Abs(y) < width; y++) { PointF p1 = InterPolateP(startP, longP, y / Math.Abs(longP.Y - startP.Y)); PointF p2 = new PointF(p1.X + shortP.X - startP.X, p1.Y + shortP.Y - startP.Y); float dis = GetHandWidthBetween(p1, p2); if (dis < min) { min = dis; ap1 = p1; ap2 = p2; } } } else { for (int X = begin; X < Convert.ToInt32(Math.Abs(longP.X - startP.X)) && Math.Abs(X) < width; X++) { PointF p1 = InterPolateP(startP, longP, X / Math.Abs(longP.X - startP.X)); PointF p2 = new PointF(p1.X + shortP.X - startP.X, p1.Y + shortP.Y - startP.Y); float dis = GetHandWidthBetween(p1, p2); if (dis < min) { min = dis; ap1 = p1; ap2 = p2; } } } CvInvoke.cvLine(image, ap1.ToPoint(), ap2.ToPoint(), new MCvScalar(0, 0, 255), 1, Emgu.CV.CvEnum.LINE_TYPE.EIGHT_CONNECTED, 0); } //CvInvoke.cvShowImage("main", tempImage); //image = binaryImg.Convert<Bgr, Byte>(); //Bitmap bmp = image.ToBitmap(); //using (Graphics g = Graphics.FromImage(bmp)) //{ // List<Rectangle> recList = new List<Rectangle>(); // double max_area = 0; // for (int i = 0; contours != null; contours = contours.HNext) // { // if ((contours.Area > Math.Pow(25, 2)) && (contours.Area < Math.Pow(300, 2))) // { // // Console.WriteLine(contours.Area); // Seq<Point> seq = contours.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE); // var pointfSeq = // from p in seq // select new PointF(p.X, p.Y); // //max_area = contours.Area; // // MCvBox2D ellp = CvInvoke.cvFitEllipse2(seq.Ptr); // MCvBox2D ellp = contours.GetMinAreaRect(); // //g.DrawPolygon(new Pen(Brushes.Red, 2), contours.ToArray()); // //Ellipse elps = PointCollection.EllipseLeastSquareFitting(pointfSeq.ToArray()); // g.TranslateTransform(ellp.center.X, ellp.center.Y); // g.RotateTransform(ellp.angle); // g.DrawRectangle(new Pen(Brushes.Red, 2), -ellp.MinAreaRect().Width / 2, // -ellp.MinAreaRect().Height / 2, // ellp.MinAreaRect().Width, // ellp.MinAreaRect().Height); // g.RotateTransform(-ellp.angle); // g.DrawRectangle(new Pen(Brushes.Red, 2), -ellp.MinAreaRect().Width / 2, // -ellp.MinAreaRect().Height / 2, // ellp.MinAreaRect().Width, // ellp.MinAreaRect().Height); // // g.DrawRectangle(new Pen(Brushes.Red, 2), -elps.MCvBox2D.MinAreaRect().Width / 2, -elps.MCvBox2D.MinAreaRect().Height / 2, elps.MCvBox2D.MinAreaRect().Width, elps.MCvBox2D.MinAreaRect().Height); // //g.DrawEllipse(new Pen(Brushes.Red, 2), -ellp.MinAreaRect().Width / 2, // // -ellp.MinAreaRect().Height / 2, // // ellp.MinAreaRect().Width, // // ellp.MinAreaRect().Height); // g.ResetTransform(); // // break; // } // } //} //imageBox1.Image = new Image<Bgr, byte>(bmp); }
public CannonBall(int cannonOwner, PointF size, PointF currentLocation, PointF targetLocation, float velocity) : this(cannonOwner, size.ToPoint(), currentLocation.ToPoint(), targetLocation.ToPoint(), velocity) { }
private bool IsHand(PointF p) { try { if (grayImg[p.ToPoint()].Intensity < 200) { return true; } return false; } catch (Exception e) { return false; } }