Heim > Artikel > Backend-Entwicklung > So erstellen Sie mit C# ein Grafikcode-Tutorial für das Minesweeper-Spiel
Dieser Artikel stellt hauptsächlich die detaillierte Erklärung vor, wie man bei Null anfängt – ein Minensuchspiel mit C# zu erstellen, was sehr praktisch ist. Freunde, die es brauchen, können darauf zurückgreifen.
Der Grund für das Erlernen von C# ist eigentlich Ganz einfach, weil ich mich schon immer sehr für Spiele interessiere und überprüft habe, dass die Hauptentwicklungssprache der beliebten Spiele-Engine Unity C# ist, also habe ich beschlossen, mit C# zu beginnen und objektorientiert zu lernen Programmiermethoden.
In der Vergangenheit habe ich mich im Grunde genommen mit der eingebetteten Entwicklung befasst. Ich habe im Grunde nur die C-Sprache verwendet. Die prozessorientierten Eigenschaften der C-Sprache sind äußerst beliebt In eingebetteten Programmierressourcen ist dies in begrenzten Situationen zwar sehr vorteilhaft, bei der Entwicklung umfangreicher Software ist diese Methode jedoch schwierig. Das Programmiermodell ist eigentlich eine Art Denkgewohnheit, nachdem man sich schon lange daran gewöhnt hat, ist es in der Tat ein schwieriger Prozess, es zu ändern ...
Apropos C#, ich habe es tatsächlich einmal studiert Semester im College, was peinlich ist, als ich es damals nicht als objektorientierte Sprache betrachtete (tatsächlich wusste ich damals nicht, was objektorientiert ist). Es gab nur einen kleinen Syntaxunterschied zur C-Sprache, was erstaunlich ist. Diese Methode kann auch programmiert werden. Am Ende des Semesters reichte ich ein mit Winform entwickeltes Minesweeper-Spiel ein, das mein C#-Lernen beendete. Danach habe ich C# nie wieder berührt.
Jetzt bin ich wieder bei C#, um unnötige Eingriffe zu vermeiden. Ich habe nicht direkt mit Unity studiert, sondern habe mich diesmal für das relativ neue WPF anstelle von WInform entschieden. Die erste Aufgabe besteht darin, wie zuvor ein Minensuchboot-Spiel zu erstellen.
Vorn geschrieben: Dieser Artikel beschreibt hauptsächlich den Programmanalyseprozess. Die spezifische Implementierungsmethode steht nicht im Mittelpunkt dieses Artikels. Freunde, die Probleme mit der Implementierung haben, können im Kommentarbereich eine Nachricht hinterlassen Quellcode oder stellen Sie Fragen^_^.
1. Analyse
1. Spielanalyse
Kommen wir nun zur Sache, wie man dieses Spiel abschließt. Abgesehen von den Details (z. B. Timing, Anzeige der Anzahl der verbleibenden Minen, Menüleiste usw.) sprechen wir einfach über den Hauptteil des Spiels: den Minenräumbereich.
Bevor das Spiel beginnt, gibt es im Minensuchgebiet eigentlich nur eines, und das ist der Block ...
Ignorieren Sie Licht und Schatten Effekte (Ja, ich habe es wieder ignoriert...), alle Blöcke haben die gleiche Farbe und reagieren auf die gleichen Ereignisse, nämlich Links- und Rechtsklicks. Klicken Sie mit der linken Maustaste, um den Block zu öffnen, und klicken Sie mit der rechten Maustaste, um den Block als Mine zu markieren. Wenn wir die Analyse fortsetzen, gibt es verschiedene Arten von Blöcken. Nachdem Sie auf einige Blöcke geklickt haben, öffnet sich um sie herum ein großer Block mit Blöcken. Unter einigen Blöcken befinden sich Minen. Klicken Sie darauf, um zu GameOver zu gelangen. Unter den Quadraten befinden sich auch Zahlen, die angeben, wie viele Minen sich in der Nähe befinden. (Natürlich habe ich die Funktion ignoriert, zwei Maustasten gleichzeitig zu drücken, um automatisch das umgebende Raster zu öffnen, und den zweiten Rechtsklick, um Fragezeichen anzuzeigen ... Aber tatsächlich werde ich später herausfinden, dass diese Funktion tatsächlich vorhanden ist sehr einfach hinzuzufügen).
Also fassen wir zunächst die Kernimplementierung des Minesweeper-Spiels zusammen:
Die Blöcke reagieren auf Mausereignisse (Linksklick, Linksklick, Rechtsklick). , Maus rein, Maus raus).
Es gibt drei Effekte, nachdem auf einen Block geklickt wurde (Bombe, Zahl, leer). Wenn er leer ist, werden alle umliegenden Blöcke automatisch erweitert.
Der Block kann nur einmal geöffnet werden und reagiert nicht mehr auf Schlüsselereignisse.
Wenn die Anzahl der Felder mit Flaggen gleich der Anzahl der Minen ist und jedes Feld mit Minen eine Flagge hat, ist das Spiel gewonnen.
Wenn der Block mit der Mine geöffnet wird, schlägt das Spiel fehl.
2. Technische Analyse der Implementierung
Haben Sie nach der Analyse festgestellt, dass das Gameplay von Minesweeper tatsächlich sehr einfach und die Technologie zu implementieren ist? Es ist nicht schwierig. Es ist alles statisch und ohne Animation.
Das Quadrat verhält sich wie eine Taste, die nur einmal gedrückt werden kann (tatsächlich habe ich die Tastensteuerung direkt während meines Studiums geerbt).
Aber dieses Mal habe ich eine umständlichere benutzerdefinierte Steuerungsmethode verwendet, um mehr C#-bezogene Dinge zu verwenden.
Der Würfel verfügt über drei Ausdrucksformen, die spezifisch sind, aber offensichtlich auch Gemeinsamkeiten aufweisen. Daher habe ich beim Entwerfen die Gemeinsamkeiten der Schaltflächen extrahiert und sie in einem abstrakten Basisklassenwürfel entworfen. Es gibt drei Arten von Würfeln, aber weil ich faul bin, habe ich zwei davon (Leerzeichen und Zahl) in der NumCube-Klasse zusammengeführt, und diejenige, die Minen enthält, ist die BombCube-Klasse. Diese beiden Klassen erben jeweils Cube.
Cube-Implementierung:
Cube-Klasse hat die folgenden Felder:
ImageSource cubeNormalPic ImageSource cubeOnPic ImageSource cubeDownPic ImageSource cubeDisablePic ImageSource cubeFlagPic
Diese 5 Felder werden verwendet, um die von Cube angezeigten Bilder in verschiedene Zustände zu setzen (normal, Mauseingabe, linke Taste gedrückt, deaktiviert, markieren)
Bool isEnable Bool isFlag
这两个字段就是标记Cube是否被使能和Flag
Image cubeImageHigh Image cubeImageLow
这2个是两个image控件,作用是用来显示图片,之所以要2个图片是因为旗子图片被设计为一个叠加在Cube上的图片。
下面再来重点讲下下面2个东西:
displayCube mouseEvent
在设计中,这是两个接口,分别用来处理鼠标事件和方块的展开。不同于直接在内部直接实现接口,将两个接口设计为Cube属性是为了能动态的修改这两个接口的实现方式,不至于每次修改都需要对Cube内的代码进行修改,且可以实现每个不同的Cube都使用不同的代码而不需要使用重写,这种方式在设计模式中也叫“策略模式”。
Cube只拥有一个方法,那就是Open,但这个方法其实也是有display接口代理实现。
public void Open() { if (displayCube != null) { displayCube.Open(this); } }
displayCube.Open(this)之所以要把自身传入,是因为Open方法要用到Cube自己的参数和方法。
BombCube继承自Cube
只添加了一个字段:
ImageSource bombPic
用来存储地雷图片.
NumCube 继承自Cube
Int bombNum
用来记录方块周围有多少个BombCube,当其为0的时候,NumCube就是显示为空的方块。
添加了一个组件lable用来显示数字Text。
interface的实现
分别为每种Cube设计了一种接口的实现方式,使用这种方式,若后期需要改为动画显示,也只需要实现一个动画的接口,赋值给对应的Cube就可以了。
二、实现
控件继承:
Wpf进行控件继承的时候需要注意,被继承的控件不能有xaml。
在继承的时候,xaml中需要加入如下语句:
< myTypes:Cube x:Class="扫雷.UserControl.NumCube" xmlns=" http:// schemas.microsoft.com/w infx/2006/xaml/presentation " xmlns:x=" http:// schemas.microsoft.com/w infx/2006/xaml " xmlns:mc=" http:// schemas.openxmlformats.org /markup-compatibility/2006 " xmlns:d=" http:// schemas.microsoft.com/e xpression/blend/2008 " mc:Ignorable="d" xmlns:myTypes="clr-namespace:扫雷.UserControl" d:DesignHeight="18" d:DesignWidth="18">
Cube 鼠标事件的实现:
鼠标事件主要是在各个事件中实现对Cube图片的变换,例如鼠标移出事件
public void MouseLeaveCube(object sender, MouseEventArgs e) { BombCube bombCube = sender as BombCube; if (bombCube.IsEnable) { isClicking = false; bombCube.cubeImageLow.Source = bombCube.cubeNormalPic; } }
关于地雷位置的生成算法实现:
游戏很重要的一个方面是,每次地雷的位置应该不同。很容易想到应该用随机数来产生地雷的位置。这就需要随机生成N个不相同的坐标。本程序的实现方法是创建一个listbd43222e33876353aff11e13a7dc75f6,之后使用随机数在0-sizeX * sizeY - 1之间随机生成一个数,检查list中是否包含该数字,若不包含则添加进list,直到list拥有N个元素停止。
List<int> BombIndexList=new List<int>(); Random ran = new Random(); do { int bombIndex = ran.Next(0,sizeX * sizeY - 1); if(!BombIndexList.Contains(bombIndex)) { BombIndexList.Add(bombIndex); } else { continue; } } while (BombIndexList.Count < BombNum); IndexList = BombIndexList;
之后根据生成的list来确定坐标上应该是NumCube还是BombCube
for (int y = 0; y < sizeY; y++) { for (int x = 0; x < sizeX;x++) { //cube属性设置 if(bombIndexList.Exists((int temp) => temp == x + y * cubeX)) { cubexMatrix[x, y] =bombCubeList[bombIndex++]; } else { numCubeList[numIndex].Text =""; cubexMatrix[x, y] =numCubeList[numIndex++]; } cubexMatrix[x, y].IsFlag =false; cubexMatrix[x, y].Margin =new Thickness(x * 18, y * 18, 0, 0); cubexMatrix[x, y].IsEnable = true; SetCubeBombNum(cubexMatrix,cubeX, cubeY); bombGrid.Children.Add(cubexMatrix[x, y]); } }
如何让空白Cube打开以后会打开周围的Cube:
因为这种打开方式有点类似于递归,需要有传染性(即若打开的也是空白Cube,则其也应该打开周围的Cube),所以执行该事件的时候一定要具有周围Cube的信息(即能获取到周围的控件)。
获取周围的Cube的方法有两种:
1.保存Cube自身的位置,并获取所有Cube的位置
2.保存周围Cube的信息
我使用的是第二种方式,之前Cube类中的Cubelist就是用来保存周围Cube的信息的。通过CubeList找到周围Cube,并触发他们的左键单击事件。
public void MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { NumCube numCube = sender as NumCube; if (numCube.IsEnable && numCube.IsFlag == false) { // 完成在控件上点击 if (isClicking) { isClicking = false; numCube.IsEnable = false; if (numCube.BombNum != 0) numCube.Text = Convert.ToString(numCube.BombNum); else { foreach (Cube cubeTemp in numCube.CubeList) { MouseButtonEventArgs args = new MouseButtonEventArgs(Mouse.PrimaryDevice, 0, MouseButton.Left); args.RoutedEvent = Cube.MouseLeftButtonDownEvent; cubeTemp.RaiseEvent(args); args.RoutedEvent = Cube.MouseLeftButtonUpEvent; cubeTemp.RaiseEvent(args); } } } } }
一些小技巧:
1.可以把一些图片的修改放在属性的set内,例如disable的图片。
public bool IsEnable { get { return isEnable; } set { isEnable = value; if (isEnable) { if (cubeNormalPic != null) cubeImageLow.Source = cubeNormalPic; } else { if (cubeDisablePic != null) cubeImageLow.Source = cubeDisablePic; } } }
2.Wpf创建控件较慢,为了提升(修改宽度长度或地雷数量之后)游戏开始速度,应该预先创建控件,并把控件放入list或者arr保存,按照需求取出。
到这扫雷游戏的制作就没什么难度技术上的难度的,只需要通过百度了解一些WPF常用的事件,控件,xalm相关的知识就能做出一个扫雷游戏啦。相关源码就不发在这了,需要的朋友可以评论中找我,这次游戏制作让我对面向对象的基本编程方法的了解有了一个很大的提升,下次应该就可以在Unity中做游戏啦 哈哈。
Das obige ist der detaillierte Inhalt vonSo erstellen Sie mit C# ein Grafikcode-Tutorial für das Minesweeper-Spiel. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!