做发包业务网站wordpress主题谁的最好
news/
2025/10/3 11:15:51/
文章来源:
做发包业务网站,wordpress主题谁的最好,网站建设流程和方法,腾讯域名怎么建设网站说明
本文根据B站up主唐老狮的课程所学所记 目录 说明本文根据B站up主唐老狮的课程所学所记 UML面向对象七大原则总体实现目标单一职责原则#xff08;SRP#xff0c;Single Responsibility Principle#xff09;开闭原则#xff08;OCP#xff0c;Open-Closed Principle…说明
本文根据B站up主唐老狮的课程所学所记 目录 说明本文根据B站up主唐老狮的课程所学所记 UML面向对象七大原则总体实现目标单一职责原则SRPSingle Responsibility Principle开闭原则OCPOpen-Closed Principle里氏替换原则LSPLiskov Substitution Principle依赖倒转原则DIPDependence Inversion Principle迪米特原则LoP of Demeter接口分离原则ISPInterface Segregation Principle合成复用原则CRPComposite Reuse Principle UML类图Game对象和场景更新接口实现多场景切换游戏对象基类的实现继承游戏对象基类的对象地图对象蛇对象蛇移动蛇转向撞墙撞身体吃食物长身体 UML
关联 如类A会有一个类B成员作为它的成员变量 直接关联 如母鸡类中有一个行为是下蛋它和气候直接关联 聚合 如地图类聚合围墙类鸟群类聚合大雁类 依赖关系 如动物类依赖于空气类和水类 复合 如公司类包含各种部门类部门类和公司类的关系就是复合关系
面向对象七大原则
总体实现目标
高内聚、低耦合使程序模块的可重用性、移植性增强 高内聚低耦合 从类角度来看减少类内部对其他类的调用 从功能模块来看减少模块之间的交互复杂度 单一职责原则SRPSingle Responsibility Principle
类被修改的几率很大因此应该专注于单一的功能。如果把多个功能放在同一个类中功能之间就形成了关联改变其中一个功能有可能中止另一个功能。 例如假设程序、策划、美术三个工种是三个类他们应该各司其职在程序世界中只应该做自己应该做的事情。
开闭原则OCPOpen-Closed Principle
对拓展开放对修改关闭 拓展开放模块的行为可以被拓展从而满足新的需求 修改关闭不允许修改模块的源代码或者尽量使修改最小化 例如继承就是最典型的开闭原则的体现可以通过添加新的子类和重写父类的方法来实现。
里氏替换原则LSPLiskov Substitution Principle
任何父类出现的地方子类都可以替代 例如用父类容器装载子类对象因为子类对象包含了父类的所有内容。
依赖倒转原则DIPDependence Inversion Principle
要依赖于抽象不要依赖于具体的实现。 例如玩家对象抽象出开枪这一行为
迪米特原则LoP of Demeter
又称最少知识原则一个对象应当对其他对象尽可能少的了解不要和陌生人说话 例如一个对象中的成员要尽可能少的直接和其他类建立关系目的是降低耦合性。
接口分离原则ISPInterface Segregation Principle
不应该强迫别人依赖他们不需要使用的方法一个接口不需要提供太多的行为一个接口应该尽量只提供一个对外的功能让别人去选择需要实现什么样的行为而不是把所有的行为都封装到一个接口当中。 例如飞行接口、走路接口、跑步接口等等虽然都是移动的行为但是我们应该把他们分为一个一个单独的接口让别人去选择使用。
合成复用原则CRPComposite Reuse Principle
尽量使用对象组合而不是继承来达到复用的目的继承关系是强耦合组合关系是低耦合。 例如脸应该是眼镜、鼻子、嘴巴、耳朵的组合而不是依次的继承。角色和装备也应该是组合而不是继承。 注意不能盲目的使用合成复用原则要在遵循迪米特原则的前提下。 UML类图 Game对象和场景更新接口
1、创建“贪吃蛇”项目创建“c1”文件 2、在“c1”文件下创建“Game”类 3、在“c1”文件下创建“ISceneUpdate”接口 4、对“ISceneUpdate”添加Update()方法 5、添加“Game”类所需成员变量
//窗口长宽
public int w 80;
public int h 20;
//当前选中场景
public ISceneUpdate nowScene;6、构造函数实现
public Game()
{Console.CursorVisible false;//鼠标是否隐藏Console.SetWindowSize(w, h);//设置窗口大小Console.SetBufferSize(w, h);//设置缓冲区大小
}7、实现游戏主循环添加start函数
//实现游戏主循环负责游戏场景逻辑的更新
public void start()
{while(true){//如果当前场景不为空就更新if(nowScene ! null){nowScene.Update();}}
}8、场景切换 ①添加E_SceneType枚举
//场景类型枚举
enum E_SceneType
{Begin,Game,End
}②添加ChangeScene函数
//场景切换
public void ChangeScene(E_SceneType type)
{
//切场景之前应该把上一个场景的绘制内容擦掉Console.Clear();switch(type){case E_SceneType.Begin:break;case E_SceneType.Game:break;case E_SceneType.End:break;}
}修改文件展示 Game.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace 贪吃蛇.c1
{//场景类型枚举enum E_SceneType{Begin,Game,End}class Game{//窗口长宽public int w 80;public int h 20;//当前选中场景public ISceneUpdate nowScene;public Game(){Console.CursorVisible false;//鼠标是否隐藏Console.SetWindowSize(w, h);//设置窗口大小Console.SetBufferSize(w, h);//设置缓冲区大小}//实现游戏主循环负责游戏场景逻辑的更新public void start(){while(true){//如果当前场景不为空就更新if(nowScene ! null){nowScene.Update();}}}//场景切换public void ChangeScene(E_SceneType type){//切场景之前应该把上一个场景的绘制内容擦掉Console.Clear();switch(type){case E_SceneType.Begin:break;case E_SceneType.Game:break;case E_SceneType.End:break;}}}
}
ISceneUpdate.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace 贪吃蛇.c1
{interface ISceneUpdate{void Update();}
}
实现多场景切换
1、创建“c2”文件添加游戏场景类GameScene为了继承ISceneUpdate则需要引用命名空间
using 贪吃蛇.c1;继承接口ISceneUpdate
namespace 贪吃蛇.c2
{class GameScene : ISceneUpdate{public void Update(){Console.SetCursorPosition(0, 0);Console.Write(游戏场景);}}
}
3、添加开始和结束场景基类BeginOrEndBaseScene,并继承ISceneUpdate
using 贪吃蛇.c1;namespace 贪吃蛇.c2
{class BeginOrEndBaseScene : ISceneUpdate{public int nowSelIndex 0;public string strTitle;public string strOne;//表示public void Update(){Console.SetCursorPosition(0, 0);Console.Write(开始或结束场景);}}
}
4、修改Game类中的ChangeScene方法
public void ChangeScene(E_SceneType type)
{//切场景之前应该把上一个场景的绘制内容擦掉Console.Clear();switch(type){case E_SceneType.Begin:nowScene new BeginOrEndBaseScene();//当前场景为开始或者结束break;case E_SceneType.Game:nowScene new GameScene();//当前场景为游戏break;case E_SceneType.End:nowScene new BeginOrEndBaseScene();break;}
}在Game类中的构造函数调用ChangeScene方法
ChangeScene(E_SceneType.Begin);主函数实现如下 运行测试如下 5、开始和结束基类逻辑实现 ①首先将Game中的w、h变量改为const常量方便通过Game直接调用 ②将BeginOrEndBaseScene改为抽象类添加抽象方法并将该类中的成员变量设置为protected。
public abstract void EnterJDoSomething();//按下j键的逻辑③实现BeginOrEndBaseScene中的Update方法
public void Update()
{//将控制台的前景色设为白色Console.ForegroundColor ConsoleColor.White;//显示标题Console.SetCursorPosition(Game.w / 2 - strTitle.Length, 5);//设置光标在窗口宽度的一半减去字体长度的位置第五行Console.Write(strTitle);//打印标题//显示第一个选项Console.SetCursorPosition(Game.w / 2 - strOne.Length, 8);Console.ForegroundColor nowSelIndex 0 ? ConsoleColor.Red : ConsoleColor.White;//根据索引不同调整选中选项颜色Console.Write(strOne);//显示第二个选项Console.SetCursorPosition(Game.w / 2 - 4, 10);Console.ForegroundColor nowSelIndex 1 ? ConsoleColor.Red : ConsoleColor.White;Console.Write(游戏结束);//检测输入switch (Console.ReadKey(true).Key) {case ConsoleKey.W://按下w键--nowSelIndex;if(nowSelIndex 0){nowSelIndex 0;}break;case ConsoleKey.S://按下s键nowSelIndex;if (nowSelIndex 0)nowSelIndex 1;break;case ConsoleKey.J://按下j键EnterJDoSomething();break;}
}④将Game类中改变场景ChangeScene方法实例化BeginOrEndBaseScene类注释掉因为该类已经是一个抽象类不能被实例化。 6、实现开始场景BeginScene类 ①将BeginScene类继承BeginOrEndBaseScene并实现构造函数将strTitle和strOne初始化
class BeginScene : BeginOrEndBaseScene
{public BeginScene() {strTitle 贪吃蛇;strOne 开始游戏;}public override void EnterJDoSomething(){}
}②为了能在此类中调用ChangeScene函数特将Game类中的ChangeScene函数设为static由于静态方法中不能调用成员变量则将nowScene也设为静态变量。 ③实现EnterJDoSomething方法
public override void EnterJDoSomething()
{if(nowSelIndex 0){Game.ChangeScene(E_SceneType.Game);}else{Environment.Exit(0);}
}④将Game类中改变场景开始被注释掉的代码改为 运行代码此时按下w或者s键盘可上下切换且在开始游戏选项中按下j键可进入游戏场景。 7、实现结束场景EndScene类
class EndScene : BeginOrEndBaseScene
{public EndScene() {strTitle 游戏结束;strOne 回到开始界面;}public override void EnterJDoSomething(){if (nowSelIndex 0){Game.ChangeScene(E_SceneType.Begin);}else{Environment.Exit(0);}}
}运行代码初始出现在结束场景。
游戏对象基类的实现 1、创建c3文件夹创建IDraw接口添加Draw方法 2、创建一个类改名为Position作为位置结构体
struct Position
{public int x;public int y; public Position(int x, int y){this.x x;this.y y;}public static bool operator (Position p1,Position p2){if(p1.x p2.x p1.y p2.y){return true;}return false;}public static bool operator !(Position p1, Position p2){if (p1.x p2.x p1.y p2.y){return false;}return true;}
}3、创建GameObject类
abstract class GameObject : IDraw
{public Position pos;public abstract void Draw();
}继承游戏对象基类的对象
1、实现地图墙壁类Wall ①创建c4文件夹添加类Wall
class Wall : GameObject
{public Wall(int x,int y) {pos new Position(x,y);}public override void Draw(){Console.SetCursorPosition(pos.x, pos.y);Console.ForegroundColor ConsoleColor.Red;Console.WriteLine();}
}2、实现食物类Food
class Food : GameObject
{public Food(int x,int y){pos new Position(x,y);}public override void Draw(){Console.SetCursorPosition(pos.x, pos.y);Console.ForegroundColor ConsoleColor.Cyan;Console.WriteLine();}
}3、实现蛇身子类和蛇身枚举
enum E_SnakeBody_Type
{Head,Body
}
class SnakeBody : GameObject
{private E_SnakeBody_Type type;public SnakeBody(E_SnakeBody_Type type,int x,int y){this.type type;this.pos new Position(x,y);}public override void Draw(){Console.SetCursorPosition(pos.x,pos.y);Console.ForegroundColor type E_SnakeBody_Type.Head ? ConsoleColor.Green : ConsoleColor.Red;Console.WriteLine(type E_SnakeBody_Type.Head ? : );}
}地图对象
1、创建c5文件夹添加地图类Map
class Map : IDraw
{private Wall[] walls;public Map(){walls new Wall[Game.w (Game.h - 3) * 2];int index 0;for (int i 0; i Game.w; i 2){walls[index] new Wall(i, 0);index;}for (int i 0; i Game.w; i 2){walls[index] new Wall(i, Game.h - 2);index;}for (int i 1; i Game.h - 2; i){walls[index] new Wall(0, i);index;}for (int i 1; i Game.h - 2; i){walls[index] new Wall(Game.w - 2, i);index;}}public void Draw(){for (int i 0; i walls.Length; i){walls[i].Draw();}}2、修改游戏场景类GameScene
class GameScene : ISceneUpdate
{private Map map;public GameScene(){map new Map();}public void Update(){map.Draw();}
}蛇对象
1、创建c6文件夹添加蛇类Snake
class Snake : IDraw
{SnakeBody[] bodys;int nowNum;public Snake(int x,int y){bodys new SnakeBody[200];bodys[0] new SnakeBody(E_SnakeBody_Type.Head,x,y);nowNum 1;}public void Draw(){for(int i 0;i nowNum;i){bodys[i].Draw();}}
}2、修改游戏场景类GameScene
class GameScene : ISceneUpdate
{private Map map;Snake snake;public GameScene(){map new Map();snake new Snake(40,10);}public void Update(){map.Draw();snake.Draw();}
}蛇移动
1、修改蛇类Snake ①添加方向枚举 ②初始化枚举变量 ③添加Move方法
enum E_MoveDir
{up,down, left, right
}
class Snake : IDraw
{SnakeBody[] bodys;int nowNum;E_MoveDir dir;public Snake(int x,int y){bodys new SnakeBody[200];bodys[0] new SnakeBody(E_SnakeBody_Type.Head,x,y);nowNum 1;dir E_MoveDir.up;}public void Move(){SnakeBody lastBody bodys[nowNum - 1];Console.SetCursorPosition(lastBody.pos.x,lastBody.pos.y);Console.WriteLine( );switch (dir){case E_MoveDir.up:--bodys[0].pos.y;break;case E_MoveDir.down:bodys[0].pos.y;break;case E_MoveDir.left:bodys[0].pos.x - 2;break;case E_MoveDir.right:bodys[0].pos.x 2;break;}}public void Draw(){for(int i 0;i nowNum;i){bodys[i].Draw();}}
}2、修改游戏场景代码GameScene
class GameScene : ISceneUpdate
{private Map map;Snake snake;int updateIndex;public GameScene(){map new Map();snake new Snake(40,10);}public void Update(){if(updateIndex % 99999999 0){map.Draw();snake.Move();snake.Draw();updateIndex 0;}updateIndex;}
}蛇转向
1、在Snake类中添加ChangeDir方法
public void ChangeDir(E_MoveDir dir)
{//不转向的情况if (this.dir dir ||nowNum 1 (this.dir E_MoveDir.left dir E_MoveDir.right|| this.dir E_MoveDir.right dir E_MoveDir.left || this.dir E_MoveDir.up dir E_MoveDir.down|| this.dir E_MoveDir.down dir E_MoveDir.up)){return;}//否则转向this.dir dir;
}2、在游戏场景类GameScene中修改Update
public void Update()
{if(updateIndex % 22222 0){map.Draw();snake.Move();snake.Draw();updateIndex 0;}updateIndex;if(Console.KeyAvailable)//按键保持激活的时候{switch(Console.ReadKey(true).Key){case ConsoleKey.W:snake.ChangeDir(E_MoveDir.up);break;case ConsoleKey.S:snake.ChangeDir(E_MoveDir.down);break;case ConsoleKey.A:snake.ChangeDir(E_MoveDir.left);break;case ConsoleKey.D:snake.ChangeDir(E_MoveDir.right);break;}}
}撞墙撞身体
1、Snake类中添加CheckEnd函数
public bool CheckEnd(Map map)
{for(int i 0;i map.walls.Length;i){if (bodys[0].pos map.walls[i].pos)//判断头与墙的位置是否相等{return true;}}for(int i 1;i nowNum;i){if (bodys[0].pos bodys[i].pos) return true;//判断头与身体的位置是否相等}return false;
}2、将Map中walls数组改为public 3、GameScene中的Update添加如下代码
吃食物
1、在Snake类中添加CheckSamePos函数
public bool CheckSamePos(Position p)
{for (int i 0; i nowNum; i){if (bodys[i].pos p)//判断传入参数是否和蛇位置相等return true;}return false;
}2、在Food类中添加RandomPos函数
public void RandomPos(Snake snake)//用于随机位置生成食物
{Random r new Random();int x r.Next(2, (Game.w / 2 - 1) * 2);int y r.Next(1, Game.h - 4);pos new Position(x, y);if(snake.CheckSamePos(pos)){RandomPos(snake); }
}3、更新Food构造函数
public Food(Snake snake)
{RandomPos(snake);
}4、在Snake类中添加CheckEatPos函数
public void CheckEatFood(Food food)
{if (bodys[0].pos food.pos)food.RandomPos(this);
}5、在GameScene中的Update方法中加入如下代码
长身体
1、在Snake类中添加AddBody方法
public void AddBody()
{SnakeBody frontBody bodys[nowNum - 1];bodys[nowNum] new SnakeBody(E_SnakeBody_Type.Body, frontBody.pos.x,frontBody.pos.y);nowNum;
}2、更新Snake中的CheckEatFood方法 3、更新Snake中的Move方法
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/925813.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!