使用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) {// It's 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 List<Obstacle> obstacles = new ArrayList<Obstacle>();private List<Enemy>  enemies = new ArrayList<Enemy>();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 List<Obstacle> getObstacles() {return obstacles;}public List<Enemy> getEnemies() {return enemies;}public Droid getDroid() {return droid;}
}

Arena是一個更復雜的對象,但是通讀代碼應該易于理解。 它基本上將所有模型歸為一個世界。 我們的游戲世界是一個競技場,其中包含機器人,敵人和障礙物等所有元素。

WIDTHHEIGHT是根據我選擇的分辨率計算的。 網格上的一個像元(塊)將寬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) {// It's 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 –最后將機器人繪制為綠色圓圈,頂部帶有棕色正方形。
請注意 ,現實世界中的競技場寬度為15(480/32)。 因此,機器人將始終位于相同的位置(7,5),并且渲染器通過使用單位度量轉換來計算其在屏幕上的位置。 在這種情況下,世界坐標系中的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)。 這些是將渲染器(視圖)添加到游戲中的行。
結果應如下圖所示(位置與玩家的機器人分開是隨機的):

第一次查看的結果

這是測試舞臺并查看模型的絕佳視圖。 創建一個新視圖而不是用形狀(正方形和圓形)顯示實際的精靈非常容易。

處理輸入和更新模型的控制器

到目前為止,該游戲什么都不做,只顯示當前世界(競技場)狀態。 為簡單起見,我們將僅更新機器人的一種狀態,即其位置。

根據用戶輸入移動機器人的步驟為:

  • 鼠標懸停時,檢查網格上單擊的單元格是否為空。 這意味著它確實包含任何可能是EnemyObstacle實例的對象。
  • 如果單元格為空,則控制器將創建一個動作,該動作將以恒定的速度移動機器人直到到達目標。
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;}
}

以下細分說明了邏輯和重要位。

#08unit代表一個像元中有多少像素,代表世界坐標中的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.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/373381.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/373381.shtml
英文地址,請注明出處:http://en.pswp.cn/news/373381.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

boost

參考博客 http://www.cnblogs.com/lidabo/p/3805487.html http://www.cppblog.com/Robertxiao/archive/2013/01/06/197022.html http://www.cnblogs.com/finallyliuyu/archive/2013/05/23/3094246.html http://www.cnblogs.com/lidabo/p/3782193.html http://www.cnblogs.com/z…

moment格式換時間_不一樣的日期、時間轉換(moment.js)

無意中遇到了一種很奇怪的日期格式&#xff0c;從接口中返回的日期是這樣的&#xff0c;如 2018-02-06T11:59:2208:00 。然而這卻不是我們想要的&#xff0c;我們要的是這種&#xff0c;YYYY-MM-DD HH:mm:ss。那么這種是怎么轉換的呢&#xff1f;這時候就可以使用一款很好用的日…

并發模式:生產者和消費者

在我15年的職業生涯中&#xff0c;生產者和消費者的問題是我僅遇到過幾次。 在大多數編程情況下&#xff0c;我們正在做的事情是以同步方式執行功能&#xff0c;其中JVM或Web容器自行處理多線程的復雜性。 但是&#xff0c;在編寫某些需要的用例時。 上周&#xff0c;我遇到了一…

POJ 1006 - Biorhythms (中國剩余定理)

B - BiorhythmsTime Limit:1000MS Memory Limit:10000KB 64bit IO Format:%I64d & %I64u Submit Status Practice POJ 1006Description 人生來就有三個生理周期&#xff0c;分別為體力、感情和智力周期&#xff0c;它們的周期長度為23天、28天和33天。每一個周期中…

子線程中更新UI線程的三個方法

1、通過handler方式&#xff0c;sendmessage。 多個類間傳遞比較麻煩&#xff0c;也懶的寫... 2、線程中通過runOnUiThread&#xff08;&#xff09; new Thread() { public void run() { //這兒是耗時操作&#xff0c;完成之后更新UI&#xff1b; runOnUiThread(new Runnab…

mysql limit acs_mysql查詢操作

簡單查詢&#xff1a;select * from 表名;避免重復&#xff1a;select distinct 字段 from 表名;條件查詢&#xff1a;select 字段,字段 from 表名 where id<5(條件);四則運算查詢&#xff1a;select id,dep_id,id*dep_id from company.employee5 where id<5;定義顯示格式…

作業管理系統數據字典

轉載于:https://www.cnblogs.com/heyangcan/p/5312394.html

使用Hive和iReport進行大數據分析

每個JJ Abrams的電視連續劇疑犯追蹤從主要人物芬奇先生一個下列敘述情節開始&#xff1a;“ 你是被監視。 政府擁有一個秘密系統-每天每天每小時都會對您進行監視的機器。 我知道是因為...我建造了它。 “當然&#xff0c;我們的技術人員知道得更多。 龐大的電氣和軟件工程師團…

docker集群管理

docker集群管理 ps&#xff1a;docker machine docker swarm docker compose 在Docker Machine發布之前&#xff0c;你可能會遇到以下問題&#xff1a; 你需要登錄主機&#xff0c;按照主機及操作系統特有的安裝以及配置步驟安裝Docker&#xff0c;使其能運行Docker…

從0學java_從零開始學JAVA(一.Java的基礎語法)

基本語法編寫 Java 程序時&#xff0c;應注意以下幾點&#xff1a;大小寫敏感&#xff1a;Java 是大小寫敏感的&#xff0c;這就意味著標識符 Hello 與 hello 是不同的。類名&#xff1a;對于所有的類來說&#xff0c;類名的首字母應該大寫。如果類名由若干單詞組成&#xff0c…

linux mount (掛載命令)詳解

掛接命令(mount) 首先&#xff0c;介紹一下掛接(mount)命令的使用方法&#xff0c;mount命令參數非常多&#xff0c;這里主要講一下今天我們要用到的。 命令格式&#xff1a;mount [-t vfstype] [-o options] device dir 其中&#xff1a; 1.-t vfstype 指定文件系統的類型&…

Android官方培訓課程中文版(v0.9.5)

http://hukai.me/android-training-course-in-chinese/index.html轉載于:https://www.cnblogs.com/xiaoyao095/p/6125715.html

使用SaxParser和完整代碼進行XML解析

SAX解析器使用回調函數&#xff08;org.xml.sax.helpers.DefaultHandler&#xff09;通知客戶端XML文檔結構。 您應該擴展DefaultHandler并重寫一些方法來實現xml解析。 覆蓋的方法是 startDocument&#xff08;&#xff09;和endDocument&#xff08;&#xff09;–在XML文檔…

mysql添加字符串日期時間_mysql學習筆記--- 字符串函數、日期時間函數

一、常見字符串函數&#xff1a;1、CHAR_LENGTH 獲取長度(字符為單位)2、FORMAT 格式化3、INSERT 替換的方式插入4、INSTR 獲取位置5、LEFT/RIGHT 取左、取右6、LENGTH 獲取長度(字節為單位)7、LTRIM/RTRIM/TRIM 去空格(左/右/自定義)8、STRCMP 字符串比較9、CONCAT 字…

Android異常和工具使用筆記

Android異常和工具使用筆記 1、r文件找不到去你的工程目錄下&#xff0c;手動的把gen刪掉&#xff0c;然后去project中刷新一下&#xff0c;在編譯看看。以前遇到過類似的問題&#xff0c;實在不行就把你的eclispe,adt升級到最新的版本吧 抓住那么一點點線索&#xff0c;就要去…

ADO.NET 核心對象簡介

ADO.NET ADO.NET是.NET中一組用于和數據源進行交互的面向對象類庫&#xff0c;提供了數據訪問的高層接口。 ADO.NET類庫在System.Data命名空間內&#xff0c;根據我們訪問的不同數據庫選擇命名空間&#xff0c;System.Data.SqlClient。 ADO.NET類最重要的優點是支持數據庫以斷開…

MongoDB與Spring Data項目

如今&#xff0c;我們所有人都在觀察NoSql解決方案的爆炸式增長。 我已經習慣了RDBMS&#xff0c;但這些并不是您可能遇到的所有挑戰的解決方案。 根據最近的經驗&#xff0c;我有機會使用MongoDB –文檔數據庫。 在本文中&#xff0c;我打算介紹將MongoDB與Spring Data項目一起…

java轉換為字符串_java – 如何從int轉換為字符串?

正常方式是Integer.toString(i)或String.valueOf(i)。串聯將工作&#xff0c;但它是非常規的&#xff0c;可能是一個難聞的氣味&#xff0c;因為它暗示作者不知道上述兩種方法(他們不知道什么&#xff1f;)。Java在使用字符串(見the documentation)時對操作符提供了特殊的支持&…

簡學LINGO(三)——實例篇

1. 裝配線平衡模型 一個裝配線含有一系列的工作站。在終于產品的加工過程中每一個工作站運行一種或者是幾種特定的任務。裝配線周期是指全部工作站完畢分配給他們各自任務所花費時間的最大值。平衡裝配線的目標是為每一個工作站分配加工任務。盡可能使每一個工作站運行同樣數量…

Hibernate緩存級別教程

開始使用Hibernate的人們常見的問題之一就是性能&#xff0c;如果您沒有太多的Hibernate經驗&#xff0c;您會發現應用程序變慢的速度。 如果啟用sql跟蹤&#xff0c;您將看到有多少查詢被發送到數據庫&#xff0c;而這些查詢幾乎不需要Hibernate知識就可以避免。 在當前文章中…