网站建设借鉴,凡科网站官网,企业所得税怎么征收比例,美工零基础的从哪开始学平时不怎么玩游戏#xff0c;有时消遣就玩玩QQ里的2D桌球#xff0c;但是玩的次数少#xff0c;不能像骨灰级玩家一样百发百中#xff0c;肿么办呢#xff1f;于是某天突发奇想#xff0c;决定自己也来做个“外挂”。说是外挂#xff0c;其实只是一个瞄准器#xff0c;… 平时不怎么玩游戏有时消遣就玩玩QQ里的2D桌球但是玩的次数少不能像骨灰级玩家一样百发百中肿么办呢于是某天突发奇想决定自己也来做个“外挂”。说是外挂其实只是一个瞄准器毕竟外挂是修改别人的软件有点违法的意思况且自己还没有能力去那么做所以自己还是弄个瞄准器做做弊过下小瘾同时也提高一下自己的编程能力。 起初也就是半年前自己尝试做一个瞄准器的初始版本用C#做想法很简单 Step1.把鼠标移到洞口获取鼠标位置 Step2.将鼠标放到要击打的球的圆心上获取鼠标当前位置 Step3.根据进球时三点共线的原则按照球的半径自动将鼠标移动到准确的击球点。 示意图如下 于是当初就按照这个想法做了开始给自己做了个C#版调用Windows API中的GetDesktopWindowGetWindowDCSetCursorPos三个函数经过简单的数学运算就基本实现了功能。代码如下 Csharp代码 using System.Drawing; using System.Windows.Forms; using System.Windows; using System.Runtime.InteropServices; using System; namespace TaiqiuGua { public partial class Form1 : Form { const int ra25; [DllImport(user32.dll)] static extern IntPtr GetDesktopWindow(); [DllImport(user32.dll)] static extern IntPtr GetWindowDC(IntPtr hWnd); [DllImport(user32.dll)] static extern bool SetCursorPos(int X, int Y); public Form1() { InitializeComponent(); } Point startP; Point endP; private void Form1_KeyDown(object sender, KeyEventArgs e) { switch(e.KeyData) { case Keys.F1: startPControl.MousePosition; break; case Keys.F2: endP Control.MousePosition; break; case Keys.D1: int x1 (int)(endP.X ra * ((endP.X - startP.X) / Math.Sqrt((endP.X - startP.X) * (endP.X - startP.X) (endP.Y - startP.Y) * (endP.Y - startP.Y)))); int y1 (int)(endP.Y ra * ((endP.Y - startP.Y) / Math.Sqrt((endP.X - startP.X) * (endP.X - startP.X) (endP.Y - startP.Y) * (endP.Y - startP.Y)))); SetCursorPos(x1, y1); break; case Keys.D2: int x2 (int)(endP.X - ra * ((-endP.X startP.X) / Math.Sqrt((-endP.X startP.X) * (-endP.X startP.X) (endP.Y - startP.Y) * (endP.Y - startP.Y)))); int y2 (int)(endP.Y ra * ((endP.Y - startP.Y) / Math.Sqrt((-endP.X startP.X) * (-endP.X startP.X) (endP.Y - startP.Y) * (endP.Y - startP.Y)))); SetCursorPos(x2, y2); break; case Keys.D3: int x3 (int)(endP.X ra * ((endP.X - startP.X) / Math.Sqrt((endP.X - startP.X) * (endP.X - startP.X) (-endP.Y startP.Y) * (-endP.Y startP.Y)))); int y3 (int)(endP.Y - ra * ((-endP.Y startP.Y) / Math.Sqrt((endP.X - startP.X) * (endP.X - startP.X) (-endP.Y startP.Y) * (-endP.Y startP.Y)))); SetCursorPos(x3, y3); break; case Keys.D4: int x4 (int)(endP.X - ra * ((-endP.X startP.X) / Math.Sqrt((-endP.X startP.X) * (-endP.X startP.X) (-endP.Y startP.Y) * (-endP.Y startP.Y)))); int y4 (int)(endP.Y - ra * ((-endP.Y startP.Y) / Math.Sqrt((-endP.X startP.X) * (-endP.X startP.X) (-endP.Y startP.Y) * (-endP.Y startP.Y)))); SetCursorPos(x4, y4); break; } GC.Collect(); } } } 使用时只需要激活瞄准器窗口按F1,F2获取鼠标位置再根据洞口位置分别选按1、2、3、4数字键就行。 经过N次试验成功率还挺高只是有时候手动放置鼠标到被击打球圆心会出现误差导致击球不准当然后来我赢了很多场比赛嘿嘿有点不道德。 再后来又用C写了一遍给同学用了。代码如下 Cpp代码 #include windows.h #include math.h int ra26; int flag0; POINT startP,endP; int x5,y5,x2,y2,x3,y3,x4,y4; LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,PSTR szCmdLine, int iCmdShow) { static TCHAR szAppName[] TEXT (GUA) ; HWND hwnd ; MSG msg ; WNDCLASS wndclass ; wndclass.style CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc WndProc ; wndclass.cbClsExtra 0 ; wndclass.cbWndExtra 0 ; wndclass.hInstance hInstance ; wndclass.hIcon LoadIcon (NULL, IDI_APPLICATION) ; wndclass.hCursor LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground (HBRUSH) GetStockObject (WHITE_BRUSH) ; wndclass.lpszMenuName NULL ; wndclass.lpszClassName szAppName ; if (!RegisterClass (wndclass)) { MessageBox ( NULL, TEXT (Program requires Windows NT!), szAppName, MB_ICONERROR) ; return 0 ; } hwnd CreateWindow (szAppName, TEXT (Programmed By DC), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL) ; ShowWindow (hwnd, iCmdShow) ; SetForegroundWindow(hwnd); MoveWindow(hwnd,100,100,200,200,TRUE); UpdateWindow (hwnd) ; while (GetMessage (msg, NULL, 0, 0)) { TranslateMessage (msg) ; DispatchMessage (msg) ; } return msg.wParam ; } void Draw(HWND hwnd,LPCSTR lpString) { HDC hdc ; PAINTSTRUCT ps ; RECT rect ; hdc BeginPaint (hwnd, ps) ; GetClientRect (hwnd, rect) ; DrawText (hdc, lpString, -1, rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER) ; EndPaint (hwnd, ps) ; ReleaseDC(hwnd,hdc); } LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam) { HBRUSH hBrush ; HDC hdc ; PAINTSTRUCT ps ; RECT rc ; switch (message) { case WM_CREATE: return 0 ; case WM_PAINT : return 0 ; case WM_KEYDOWN: switch (wParam) { case VK_F1: GetCursorPos(startP); flag1; InvalidateRect (hwnd, NULL, TRUE) ; Draw(hwnd,第1点已锁定!); break ; case VK_F2: GetCursorPos(endP); flag2; InvalidateRect (hwnd, NULL, TRUE) ; Draw(hwnd,第2点已锁定!); break ; case 0x31: x5 (int)(endP.x ra * ((endP.x - startP.x) / sqrt((endP.x - startP.x) * (endP.x - startP.x) (endP.y - startP.y) * (endP.y - startP.y)))); y5 (int)(endP.y ra * ((endP.y - startP.y) / sqrt((endP.x - startP.x) * (endP.x - startP.x) (endP.y - startP.y) * (endP.y - startP.y)))); SetCursorPos(x5, y5); break; case 0x32: x2 (int)(endP.x - ra * ((-endP.x startP.x) / sqrt((-endP.x startP.x) * (-endP.x startP.x) (endP.y - startP.y) * (endP.y - startP.y)))); y2 (int)(endP.y ra * ((endP.y - startP.y) / sqrt((-endP.x startP.x) * (-endP.x startP.x) (endP.y - startP.y) * (endP.y - startP.y)))); SetCursorPos(x2, y2); break; case 0x33: x3 (int)(endP.x ra * ((endP.x - startP.x) / sqrt((endP.x - startP.x) * (endP.x - startP.x) (-endP.y startP.y) * (-endP.y startP.y)))); y3 (int)(endP.y - ra * ((-endP.y startP.y) / sqrt((endP.x - startP.x) * (endP.x - startP.x) (-endP.y startP.y) * (-endP.y startP.y)))); SetCursorPos(x3, y3); break; case 0x34: x4 (int)(endP.x - ra * ((-endP.x startP.x) / sqrt((-endP.x startP.x) * (-endP.x startP.x) (-endP.y startP.y) * (-endP.y startP.y)))); y4 (int)(endP.y - ra * ((-endP.y startP.y) / sqrt((-endP.x startP.x) * (-endP.x startP.x) (-endP.y startP.y) * (-endP.y startP.y)))); SetCursorPos(x4, y4); break; } return 0; case WM_SIZE : if(flag1) { Draw(hwnd,第1点已锁定); } else if(flag2) { Draw(hwnd,第2点已锁定); } else {InvalidateRect (hwnd, NULL, TRUE) ; } return 0 ; case WM_KILLFOCUS: InvalidateRect (hwnd, NULL, TRUE) ; hdc BeginPaint (hwnd, ps) ; GetClientRect (hwnd, rc) ; hBrush CreateSolidBrush ( RGB(255,0,0) ) ; FillRect (hdc, rc, hBrush) ; EndPaint (hwnd, ps) ; ReleaseDC(hwnd,hdc); DeleteObject (hBrush) ; return 0; case WM_SETFOCUS: InvalidateRect (hwnd, NULL, TRUE) ; if(flag1) { Draw(hwnd,第1点已锁定); } else if(flag2) { Draw(hwnd,第2点已锁定); } return 0; case WM_DESTROY : PostQuitMessage (0) ; return 0 ; } return DefWindowProc(hwnd, message, wParam, lParam) ; } 但是问题还存在就是手动找圆心太麻烦一般用触摸板比鼠标方便但是仍然很不智能于是一直想着用图像处理的方法去自动找圆心。 这几天在做数模经常用到Matlab刚做了一道要处理图像的题正好想起这个问题来于是搁置的瞄准器继续开始完善了。 很快就有了思路通过C#截图然后Matlab进行图像滤波灰度化二值化以及边缘提取然后进行圆曲线拟合最后找到圆心返回到C#中使用代替手动找点。 首先我用Matlab写了个函数 Html代码 function [x,y]findcenter() %close all,clear,clc format short aimread(E:\360data\重要数据\桌面\test.bmp); brgb2gray(a);%转化为灰度图像 %figure;imshow(b) bfilter2(fspecial(average,1),b)/255; %bmedfilt2(b);%中值滤波 levelgraythresh(b);%自动获取灰度图片的阈值 cim2bw(b,level);%二值化 %figure;imshow(c) bwedge(c,canny); bw1~bw;%取反黑变白白变黑 %figure;imshow(bw1) %figure;imshow(bw1) [yf,xf]find(bw10); xminmin(xf); xmaxmax(xf); yminmin(yf); ymaxmax(yf); %cirPx[xmin;(xmax-xmin)/2;(xmax-xmin)/2;xmax] %cirPy[(ymax-ymin)/2;ymin;ymax;(ymax-ymin)/2] %fitellipse(cirPx,cirPy) centerX(xmaxxmin)/2; centerY(ymaxymin)/2; ra(ymax-ymin)/2; xcenterX;ycenterY; %hold on %x0:size(bw1,2); %degree[0:0.01:pi*2]; %degree[0:0.01:pi*2]; %plot(ra*cos(degree)centerX,ra*sin(degree)centerY,r-); %plot(centerX,centerY,r); 然后用Matlab2010b里的deploytool导出.net能使用的程序集dll文件不知道为什么malab2009b在build时出现.net framework相关的错误通过C#添加引用调用其返回的参数成功完成自动拾取圆心。 改进后代码如下 Csharp代码 using System.Drawing; using System.Windows.Forms; using System.Windows; using System.Runtime.InteropServices; using System; using MathWorks.MATLAB.NET.Arrays; using MathWorks.MATLAB.NET.Utility; using findcenter; namespace TaiqiuGua { public partial class Form1 : Form { const int ra25; [DllImport(user32.dll)] static extern IntPtr GetDesktopWindow(); [DllImport(user32.dll)] static extern IntPtr GetWindowDC(IntPtr hWnd); [DllImport(user32.dll)] static extern bool SetCursorPos(int X, int Y); public Form1() { InitializeComponent(); } Point startP,startP1; Point endP,endP1; private void Form1_KeyDown(object sender, KeyEventArgs e) { switch(e.KeyData) { case Keys.F1: startPControl.MousePosition; break; case Keys.F5: endP Control.MousePosition; break; case Keys.F2: startP1 Control.MousePosition; break; case Keys.F3: endP1 Control.MousePosition; break; case Keys.D1: int x1 (int)(endP.X ra * ((endP.X - startP.X) / Math.Sqrt((endP.X - startP.X) * (endP.X - startP.X) (endP.Y - startP.Y) * (endP.Y - startP.Y)))); int y1 (int)(endP.Y ra * ((endP.Y - startP.Y) / Math.Sqrt((endP.X - startP.X) * (endP.X - startP.X) (endP.Y - startP.Y) * (endP.Y - startP.Y)))); SetCursorPos(x1, y1); break; case Keys.D2: int x2 (int)(endP.X - ra * ((-endP.X startP.X) / Math.Sqrt((-endP.X startP.X) * (-endP.X startP.X) (endP.Y - startP.Y) * (endP.Y - startP.Y)))); int y2 (int)(endP.Y ra * ((endP.Y - startP.Y) / Math.Sqrt((-endP.X startP.X) * (-endP.X startP.X) (endP.Y - startP.Y) * (endP.Y - startP.Y)))); SetCursorPos(x2, y2); break; case Keys.D3: int x3 (int)(endP.X ra * ((endP.X - startP.X) / Math.Sqrt((endP.X - startP.X) * (endP.X - startP.X) (-endP.Y startP.Y) * (-endP.Y startP.Y)))); int y3 (int)(endP.Y - ra * ((-endP.Y startP.Y) / Math.Sqrt((endP.X - startP.X) * (endP.X - startP.X) (-endP.Y startP.Y) * (-endP.Y startP.Y)))); SetCursorPos(x3, y3); break; case Keys.D4: int x4 (int)(endP.X - ra * ((-endP.X startP.X) / Math.Sqrt((-endP.X startP.X) * (-endP.X startP.X) (-endP.Y startP.Y) * (-endP.Y startP.Y)))); int y4 (int)(endP.Y - ra * ((-endP.Y startP.Y) / Math.Sqrt((-endP.X startP.X) * (-endP.X startP.X) (-endP.Y startP.Y) * (-endP.Y startP.Y)))); SetCursorPos(x4, y4); break; case Keys.F4: //Graphics g1 pictureBox1.CreateGraphics(); //g1.CopyFromScreen(startP1.X,startP1.Y,0,0,new Size(endP1.X-startP1.X,endP1.Y-startP1.Y)); int wendP1.X - startP1.X; int hendP1.Y - startP1.Y; Bitmap bmSave new Bitmap(w,h); Graphics gGraphics.FromImage(bmSave); g.CopyFromScreen(startP1.X,startP1.Y,0,0,new Size(w,h),CopyPixelOperation.SourceCopy); bmSave.Save(E:\360data\重要数据\桌面\test.bmp); g.Dispose(); //g1.Dispose(); bmSave.Dispose(); findcenter.Class1 f new findcenter.Class1(); MWArray centerx f.findcenter(); MWArray centery f.findy(); double[,] x (double[,])centerx.ToArray(); double[,] y (double[,])centery.ToArray(); SetCursorPos((int)(x[0, 0] startP1.X), (int)(y[0, 0] startP1.Y)); //int [] dcenter.Dimensions; //int xint.Parse((center[1, 1]).ToString()); //int y int.Parse((center[1, 2]).ToString()); //MessageBox.Show((y[0,0]).ToString()); f.Dispose(); break; } GC.Collect(); } private void Form1_Activated(object sender, EventArgs e) { //this.BackColor Color.Red; } private void Form1_Deactivate(object sender, EventArgs e) { //this.BackColor Color.Blue; } } } 经试验成功率也很高偶尔出现不准估计是边缘提取和计算精度的问题但是大多数偏差可以手动修正。 到此为止改进版全部完成。希望以后继续改进更加智能化。C# 真是码农的利器啊