当前位置: 首页 > news >正文

自己搭建的网站可以收费吗浙江1万家企业

自己搭建的网站可以收费吗,浙江1万家企业,用什么软件开发app,河间市做网站spring-mvc教程游戏开发中一种有用的体系结构模式是MVC#xff08;模型视图控制器#xff09;模式。 它有助于分离输入逻辑#xff0c;游戏逻辑和UI#xff08;渲染#xff09;。 在任何游戏开发项目的早期阶段#xff0c;它的用途很快就会被注意到#xff0c;因为它可以… spring-mvc教程 游戏开发中一种有用的体系结构模式是MVC模型视图控制器模式。 它有助于分离输入逻辑游戏逻辑和UI渲染。 在任何游戏开发项目的早期阶段它的用途很快就会被注意到因为它可以快速更改内容而无需在应用程序的所有层中进行过多的代码重做。 下图是模型视图控制器概念的最简单逻辑表示。 模型-视图-控制器模式 用法示例 在玩家控制机器人的示例游戏中可能会发生以下情况 1 –用户单击/轻击屏幕上的某个位置。 2 – 控制器处理单击/点击并将事件转换为适当的操作。 例如如果一个敌人占领了地形则创建攻击动作如果它是空的地形则创建移动动作最后如果用户轻拍的地方被障碍物占据则什么都不做。 3 – 控制器会相应地更新机器人的 模型 状态。 如果创建了移动动作那么它将改变位置如果发起了攻击则它将触发。 4 – 渲染器 视图 收到有关状态更改的通知并渲染世界的当前状态。 这意味着模型机器人对如何绘制自己或如何更改其状态位置命中点一无所知。 他们是愚蠢的实体。 在Java中它们也称为POJO普通的Java对象。 控制器负责更改模型的状态并通知渲染器。 为了绘制模型渲染器必须引用模型机器人和任何其他实体及其状态。 从典型的游戏体系结构中我们知道 主循环充当超级控制器它会更新状态然后每秒将对象呈现到屏幕上多次。 我们可以将所有更新和渲染与机器人一起放入主循环但这很麻烦。 让我们确定游戏的不同方面问题。 型号 玩家控制的机器人 机器人可以移动的竞技场 一些障碍 一些敌人要射击 控制器 主循环和输入处理程序 控制器处理玩家输入 在玩家的机器人上执行动作移动攻击的控制器 观点 世界渲染器–将对象渲染到屏幕上 创建项目 为了简单起见我这次选择了applet并将尝试使其简短。 该项目具有以下结构 MVC –项目结构 文件Droids.java是applet包含主循环。 package net.obviam.droids;import java.applet.Applet; import java.awt.Color; import java.awt.Event; import java.awt.Graphics; import java.awt.image.BufferedImage;public class Droids extends Applet implements Runnable {private static final long serialVersionUID -2472397668493332423L;public void start() {new Thread(this).start();}public void run() {setSize(480, 320); // For AppletViewer, remove later.// Set up the graphics stuff, double-buffering.BufferedImage screen new BufferedImage(480, 320, BufferedImage.TYPE_INT_RGB);Graphics g screen.getGraphics();Graphics appletGraphics getGraphics();long delta 0l;// Game loop.while (true) {long lastTime System.nanoTime();g.setColor(Color.black);g.fillRect(0, 0, 480, 320);// Draw the entire results on the screen.appletGraphics.drawImage(screen, 0, 0, null);// Lock the frame ratedelta System.nanoTime() - lastTime;if (delta 20000000L) {try {Thread.sleep((20000000L - delta) / 1000000L);} catch (Exception e) {// Its an interrupted exception, and nobody cares}}if (!isActive()) {return;}}}public boolean handleEvent(Event e) {return false;} } 将上面的代码作为applet运行无非是设置主循环并将屏幕涂成黑色。 结构中有3个程序包各个组件都将放在那儿。 net.obviam.droids.model将包含所有模型 net.obviam.droids.view将包含所有渲染器 net.obviam.droids.controller将包含所有控制器 创建模型 机器人 Droid.java package net.obviam.droids.model;public class Droid {private float x;private float y;private float speed 2f;private float rotation 0f;private float damage 2f;public float getX() {return x;}public void setX(float x) {this.x x;}public float getY() {return y;}public void setY(float y) {this.y y;}public float getSpeed() {return speed;}public void setSpeed(float speed) {this.speed speed;}public float getRotation() {return rotation;}public void setRotation(float rotation) {this.rotation rotation;}public float getDamage() {return damage;}public void setDamage(float damage) {this.damage damage;} } 它是一个简单的Java对象对周围世界一无所知。 它具有位置旋转速度和损坏。 这些状态由成员变量定义可以通过getter和setter方法访问。 游戏需要更多模型地图上的障碍物和敌人。 为简单起见障碍物将仅在地图上定位而敌人将是站立的物体。 该地图将是一个二维数组其中包含敌人障碍物和机器人。 该地图将被称为Arena以与标准Java地图区分开并且在构建地图时会填充障碍物和敌人。 Obstacle.java package net.obviam.droids.model;public class Obstacle {private float x;private float y;public Obstacle(float x, float y) {this.x x;this.y y;}public float getX() {return x;}public float getY() {return y;} } Enemy.java package net.obviam.droids.model;public class Enemy {private float x;private float y;private int hitpoints 10;public Enemy(float x, float y) {this.x x;this.y y;}public float getX() {return x;}public float getY() {return y;}public int getHitpoints() {return hitpoints;}public void setHitpoints(int hitpoints) {this.hitpoints hitpoints;} } Arena.java package net.obviam.droids.model;import java.util.ArrayList; import java.util.List; import java.util.Random;public class Arena {public static final int WIDTH 480 / 32;public static final int HEIGHT 320 / 32;private static Random random new Random(System.currentTimeMillis());private Object[][] grid;private ListObstacle obstacles new ArrayListObstacle();private ListEnemy enemies new ArrayListEnemy();private Droid droid;public Arena(Droid droid) {this.droid droid;grid new Object[HEIGHT][WIDTH];for (int i 0; i WIDTH; i) {for (int j 0; j HEIGHT; j) {grid[j][i] null;}}// add 5 obstacles and 5 enemies at random positionsfor (int i 0; i 5; i) {int x random.nextInt(WIDTH);int y random.nextInt(HEIGHT);while (grid[y][x] ! null) {x random.nextInt(WIDTH);y random.nextInt(HEIGHT);}grid[y][x] new Obstacle(x, y);obstacles.add((Obstacle) grid[y][x]);while (grid[y][x] ! null) {x random.nextInt(WIDTH);y random.nextInt(HEIGHT);}grid[y][x] new Enemy(x, y);enemies.add((Enemy) grid[y][x]);}}public ListObstacle getObstacles() {return obstacles;}public ListEnemy getEnemies() {return enemies;}public Droid getDroid() {return droid;} } Arena是一个更复杂的对象但是通读代码应该易于理解。 它基本上将所有模型归为一个世界。 我们的游戏世界是一个竞技场其中包含机器人敌人和障碍物等所有元素。 WIDTH和HEIGHT是根据我选择的分辨率计算的。 网格上的一个像元块将高32像素所以我只计算网格上有多少个像元。 在构造函数第19行中建立了网格并随机放置了5个障碍物和5个敌人。 这将构成起步舞台和我们的游戏世界。 为了使主循环保持整洁我们将把更新和渲染委托给GameEngine 。 这是一个简单的类它将处理用户输入更新模型的状态并渲染世界。 这是一个很小的粘合框架可以实现所有这些功能。 GameEngine.java存根 package net.obviam.droids.controller;import java.awt.Event; import java.awt.Graphics;public class GameEngine {/** handle the Event passed from the main applet **/public boolean handleEvent(Event e) {switch (e.id) {case Event.KEY_PRESS:case Event.KEY_ACTION:// key pressedbreak;case Event.KEY_RELEASE:// key releasedbreak;case Event.MOUSE_DOWN:// mouse button pressedbreak;case Event.MOUSE_UP:// mouse button releasedbreak;case Event.MOUSE_MOVE:// mouse is being movedbreak;case Event.MOUSE_DRAG:// mouse is being dragged (button pressed)break;}return false;}/** the update method with the deltaTime in seconds **/public void update(float deltaTime) {// empty}/** this will render the whole world **/public void render(Graphics g) {// empty} } 要使用该引擎需要修改Droids.java类。 我们需要创建GameEngine类的实例并在适当的时候调用update()和render()方法。 另外我们需要将输入处理委托给引擎。 添加以下行 声明私有成员并实例化它。 private GameEngine engine new GameEngine(); 修改后的游戏循环如下所示 while (true) {long lastTime System.nanoTime();g.setColor(Color.black);g.fillRect(0, 0, 480, 320);// Update the state (convert to seconds)engine.update((float)(delta / 1000000000.0));// Render the worldengine.render(g);// Draw the entire results on the screen.appletGraphics.drawImage(screen, 0, 0, null);// Lock the frame ratedelta System.nanoTime() - lastTime;if (delta 20000000L) {try {Thread.sleep((20000000L - delta) / 1000000L);} catch (Exception e) {// Its an interrupted exception, and nobody cares}}} 高亮显示的行7-10包含对update()和render()方法的委托。 请注意从纳秒到秒的转换是几秒钟。 在几秒钟内工作非常有用因为我们可以处理现实价值。 重要说明 更新需要在计算增量自上次更新以来经过的时间之后进行。 更新后也应调用渲染器以便它将显示对象的当前状态。 请注意每次在渲染涂成黑色之前都会清除屏幕。 最后要做的是委派输入处理。 用以下代码片段替换当前的handleEvent方法 public boolean handleEvent(Event e) {return engine.handleEvent(e);} 非常简单直接的委托。 运行小程序不会产生特别令人兴奋的结果。 只是黑屏。 这是有道理的因为除了每个周期要清除的屏幕之外所有内容都只是一个存根。 初始化模型世界 我们的游戏需要机器人和一些敌人。 按照设计世界就是我们的Arena 。 通过实例化它我们创建了一个世界检查Arena的构造函数。 我们将在GameEngine创建世界因为引擎负责告诉视图要渲染的内容。 我们还需要在此处创建Droid 因为Arena需要它的构造函数。 最好将其分开因为机器人将由玩家控制。 将以下成员与初始化世界的构造函数一起添加到GameEngine 。 private Arena arena;private Droid droid;public GameEngine() {droid new Droid();// position droid in the middledroid.setX(Arena.WIDTH / 2);droid.setY(Arena.HEIGHT / 2);arena new Arena(droid);} 注意 Arena的构造函数需要修改因此Droid会在障碍物和敌人之前添加到网格中。 ...// add the droidgrid[(int)droid.getY()][(int) droid.getX()] droid; ... 再次运行该applet不会更改输出但是我们已经创建了世界。 我们可以添加日志记录以查看结果但这不会很有趣。 让我们创建第一个视图它将揭示我们的世界。 创建第一个视图/渲染器 我们在创建竞技场和世界上付出了很多努力我们渴望看到它。 因此我们将创建一个快速而肮脏的渲染器来揭示整个世界。 快速而肮脏的意思是除了简单的正方形圆形和占位符之外没有其他奇特的图像。 一旦我们对游戏元素感到满意就可以在更精细的视图上进行操作以用精美的图形替换正方形和圆形。 这就是去耦能力的光芒所在。 渲染世界的步骤。 绘制网格以查看单元格在哪里。 障碍物将被绘制为蓝色方块它们将占据细胞 敌人将是红色圆圈 机器人将是带有棕色正方形的绿色圆圈 首先我们创建渲染器界面。 我们使用它来建立与渲染器交互的单一方法这将使创建更多视图而不影响游戏引擎变得容易。 要了解更多关于为什么是一个好主意检查这个和这个 。 在view包中创建一个接口。 Renderer.java package net.obviam.droids.view;import java.awt.Graphics;public interface Renderer {public void render(Graphics g); } 就这些。 它包含一种方法 render(Graphics g) 。 Graphics g是从applet传递的画布。 理想情况下该接口将是不可知的并且每个实现都将使用不同的后端但是此练习的目的是描述MVC而不是创建完整的框架。 因为我们选择了applet所以我们需要Graphics对象。 具体的实现如下所示 SimpleArenaRenderer.java 在view包中 package net.obviam.droids.view;import java.awt.Color; import java.awt.Graphics;import net.obviam.droids.model.Arena; import net.obviam.droids.model.Droid; import net.obviam.droids.model.Enemy; import net.obviam.droids.model.Obstacle;public class SimpleArenaRenderer implements Renderer {private Arena arena;public SimpleArenaRenderer(Arena arena) {this.arena arena;}Overridepublic void render(Graphics g) {// render the gridint cellSize 32; // hard codedg.setColor(new Color(0, 0.5f, 0, 0.75f));for (int i 0; i Arena.WIDTH; i) {g.drawLine(i * cellSize, 0, i * cellSize, Arena.HEIGHT * cellSize);if (i Arena.WIDTH)g.drawLine(0, i * cellSize, Arena.WIDTH * cellSize, i * cellSize);}// render the obstaclesg.setColor(new Color(0, 0, 1f));for (Obstacle obs : arena.getObstacles()) {int x (int) (obs.getX() * cellSize) 2;int y (int) (obs.getY() * cellSize) 2;g.fillRect(x, y, cellSize - 4, cellSize - 4);}// render the enemiesg.setColor(new Color(1f, 0, 0));for (Enemy enemy : arena.getEnemies()) {int x (int) (enemy.getX() * cellSize);int y (int) (enemy.getY() * cellSize);g.fillOval(x 2, y 2, cellSize - 4, cellSize - 4);}// render player droidg.setColor(new Color(0, 1f, 0));Droid droid arena.getDroid();int x (int) (droid.getX() * cellSize);int y (int) (droid.getY() * cellSize);g.fillOval(x 2, y 2, cellSize - 4, cellSize - 4);// render square on droidg.setColor(new Color(0.7f, 0.5f, 0f));g.fillRect(x 10, y 10, cellSize - 20, cellSize - 20);} } 第13 – 17行声明了Arena对象并确保在构造渲染器时设置了该对象。 我将其称为ArenaRenderer是因为我们将渲染竞技场世界。 渲染器中唯一的方法是render()方法。 让我们一步一步看看。 22 –声明像元大小以像素为单位。 它是32。与Arena类中一样它是硬编码的。 23 –28 –正在绘制网格。 这是一个简单的网格。 首先将颜色设置为深绿色并以相等的距离绘制线条。 绘制障碍物–蓝色方块 31 –将笔刷颜色设置为蓝色。 32 –36 –遍历舞台上的所有障碍物并为每个障碍物绘制一个蓝色填充的矩形该矩形稍小于网格上的单元格。 39 –44 –将颜色设置为红色并通过遍历竞技场中的敌人在相应位置绘制一个圆圈。 47 –54 –最后将机器人绘制为绿色圆圈顶部带有棕色正方形。 请注意 现实世界中的竞技场宽度为15480/32。 因此机器人将始终位于相同的位置75并且渲染器通过使用单位度量转换来计算其在屏幕上的位置。 在这种情况下世界坐标系中的1个单位在屏幕上为32个像素。 通过修改GameEngine以使用新创建的视图 SimpleArenaRenderer 我们得到了结果。 public class GameEngine {private Arena arena;private Droid droid;private Renderer renderer;public GameEngine() {droid new Droid();// position droid in the middledroid.setX(Arena.WIDTH / 2);droid.setY(Arena.HEIGHT / 2);arena new Arena(droid);// setup renderer (view)renderer new SimpleArenaRenderer(arena);}/** ... code stripped ... **//** this will render the whole world **/public void render(Graphics g) {renderer.render(g);} } 注意突出显示的行5、15、22。 这些是将渲染器视图添加到游戏中的行。 结果应如下图所示位置与玩家的机器人分开是随机的 第一次查看的结果 这是测试舞台并查看模型的绝佳视图。 创建一个新视图而不是形状正方形和圆形显示实际的精灵非常容易。 处理输入和更新模型的控制器 到目前为止该游戏什么都不做只显示当前的世界状态竞技场。 为简单起见我们将仅更新机器人的一种状态即其位置。 根据用户输入移动机器人的步骤为 鼠标悬停时检查网格上单击的单元格是否为空。 这意味着它确实包含任何可能是Enemy或Obstacle实例的对象。 如果单元格为空则控制器将创建一个动作该动作将使机器人以恒定的速度移动直到到达目的地为止。 package net.obviam.droids.controller;import net.obviam.droids.model.Arena; import net.obviam.droids.model.Droid;public class ArenaController {private static final int unit 32;private Arena arena;/** the target cell **/private float targetX, targetY;/** true if the droid moves **/private boolean moving false;public ArenaController(Arena arena) {this.arena arena;}public void update(float delta) {Droid droid arena.getDroid();if (moving) {// move on Xint bearing 1;if (droid.getX() targetX) {bearing -1;}if (droid.getX() ! targetX) {droid.setX(droid.getX() bearing * droid.getSpeed() * delta);// check if arrivedif ((droid.getX() targetX bearing -1)|| (droid.getX() targetX bearing 1)) droid.setX(targetX);}// move on Ybearing 1;if (droid.getY() targetY) {bearing -1;}if (droid.getY() ! targetY) {droid.setY(droid.getY() bearing * droid.getSpeed() * delta);// check if arrivedif ((droid.getY() targetY bearing -1)|| (droid.getY() targetY bearing 1)) droid.setY(targetY);}// check if arrivedif (droid.getX() targetX droid.getY() targetY)moving false;}}/** triggered with the coordinates every click **/public boolean onClick(int x, int y) {targetX x / unit;targetY y / unit;if (arena.getGrid()[(int) targetY][(int) targetX] null) {// start moving the droid towards the targetmoving true;return true;}return false;} } 以下细分说明了逻辑和重要位。 08 – unit代表一个像元中有多少像素在世界坐标中代表1个单位。 它是硬编码的不是最佳的但是对于演示来说已经足够了。 09 –控制器将控制的Arena 。 在构造控制器时设置第16行。 12 –点击的目标坐标以世界单位表示。 14 –机器人移动时true 。 这是“移动”动作的状态。 理想情况下这应该是一个独立的类但是为了演示控制器并保持简洁我们将在控制器内部共同编写一个动作。 20 –一种update方法用于以恒定速度经过的时间更新机器人的位置。 这非常简单它可以同时检查X和Y位置如果它们与目标位置不同它会根据机器人的速度更新机器人的相应位置X或Y。 如果机器人在目标位置则更新move状态变量以完成移动动作。 这不是一个很好的书面动作没有对沿途发现的障碍物或敌人进行碰撞检查也没有发现路径。 它只是更新状态。 52 –发生“鼠标向上”事件时将调用onClick(int x, int y)方法。 它检查单击的单元格是否为空如果为空则通过将状态变量设置为true来启动“移动”操作 53-54 –将屏幕坐标转换为世界坐标。 这是控制器。 要使用它必须更新GameEngine 。 更新的GameEngine.java package net.obviam.droids.controller;import java.awt.Event; import java.awt.Graphics;import net.obviam.droids.model.Arena; import net.obviam.droids.model.Droid; import net.obviam.droids.view.Renderer; import net.obviam.droids.view.SimpleArenaRenderer;public class GameEngine {private Arena arena;private Droid droid;private Renderer renderer;private ArenaController controller;public GameEngine() {droid new Droid();// position droid in the middledroid.setX(Arena.WIDTH / 2);droid.setY(Arena.HEIGHT / 2);arena new Arena(droid);// setup renderer (view)renderer new SimpleArenaRenderer(arena);// setup controllercontroller new ArenaController(arena);}/** handle the Event passed from the main applet **/public boolean handleEvent(Event e) {switch (e.id) {case Event.KEY_PRESS:case Event.KEY_ACTION:// key pressedbreak;case Event.KEY_RELEASE:// key releasedbreak;case Event.MOUSE_DOWN:// mouse button pressedbreak;case Event.MOUSE_UP:// mouse button releasedcontroller.onClick(e.x, e.y);break;case Event.MOUSE_MOVE:// mouse is being movedbreak;case Event.MOUSE_DRAG:// mouse is being dragged (button pressed)break;}return false;}/** the update method with the deltaTime in seconds **/public void update(float deltaTime) {controller.update(deltaTime);}/** this will render the whole world **/public void render(Graphics g) {renderer.render(g);} } 更改将突出显示。 16 –声明控制器。 28 –实例化控制器。 46 –委托鼠标上移事件。 60 –在控制器上调用update方法。 运行小程序您可以单击地图如果单元格为空则机器人将移动到该位置。 练习 创建一个视图该视图将显示实体的图像/精灵而不是绘制的形状。 提示 使用BufferedImage来实现。 将移动动作提取到新类中。 单击敌人时添加新的动作攻击 提示创建被发射到目标的项目符号实体。 您可以以更高的速度使用移动动作。 当hitpoint降低到0时敌人将被消灭。 使用不同的图像表示不同的状态。 源代码 https://github.com/obviam/mvc-droids或下载为zip文件。 您也可以使用git $ git clone git://github.com/obviam/mvc-droids.git 参考 使用MVC模式构建游戏– JCG合作伙伴的 教程和简介   反对谷物博客的Impaler。 翻译自: https://www.javacodegeeks.com/2012/02/building-games-using-mvc-pattern.htmlspring-mvc教程
http://www.zqtcl.cn/news/409646/

相关文章:

  • 宁阳网站设计家电网站设计方案
  • 网站备案icp秦皇岛黄金海岸
  • dedecms 金融类网站模板wordpress dux5.3
  • 学校网站源码wordpress向网站上传文件怎么做
  • 电子商务网站建设说课稿济南网站建设方案报价
  • 谈谈设计和建设网站体会wordpress header在哪
  • 360免费建站怎么进不去域名托管
  • 做网站视频存储网站建设有云端吗
  • 建网站如何上传南通 网站优化
  • 青海学会网站建设公司果汁网站模板
  • 10_10_网站建站怎么做网站链接支付
  • 九台网站甘肃网站优化
  • phpcms 网站源码建设银行科技中心网站首页
  • 营销型网站建设php源码无锡设计网站公司
  • 在线制作简历的网站绍兴seo全网营销
  • 个人做网站接装修活哪个网站好长沙企业网站建设分公司
  • 青岛网站制作辰星辰中国万网icp网站备案专题
  • 做淘宝相关网站上海网站建设做物流一
  • 服装配件网站建设 中企动力静态网站 后台
  • 做网站较好的框架网站建设的定位是什么
  • 如何保护自己的网站桂林医院网站建设
  • 产品品牌策划方案佛山网站优化美姿姿seo
  • 北京城建一建设发展有限公司网站大连在哪个省的什么位置
  • 北京知名网站建设公司排名学校诗歌网站建设
  • 个人做网站接装修活哪个网站好上海造价信息网官网
  • 网页上做网会员网站备案怎么写oa报表网站开发
  • 郑州服装网站建设网站的层级
  • 东莞建设网站制作怎么建立信息网站平台
  • 网站建设的公司服务手机上做ppt的软件
  • 体育网站模版爱站网