91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android游戲開發十日通(3)-創建第一個Android游戲

發布時間:2020-07-02 11:08:29 來源:網絡 閱讀:170 作者:拳四郎 欄目:開發技術

提要

有了前面的學習基礎,我們就可以開始開發游戲了,當然,現階段只是學習為主。

下面要做的一個游戲叫做 Star Guard,一款非常棒的獨立游戲,畫面非常有愛,難度不小,不過有無限生命可以玩。

鍵盤的上下左右控制小人,x開火,z跳躍。

Android游戲開發十日通(3)-創建第一個Android游戲


今天我們要做的就是搭建舞臺,創建項目的骨架。

最終的效果看起來是這樣:

Android游戲開發十日通(3)-創建第一個Android游戲


當然,可以同時部署在手機和PC上。


搭建工程

偷懶的話直接用上次創建的工程就ok,如果想重新創建的話,用gdx-setup-ui也很快。
在eclipse中導入三個工程。
看起來就像這樣:
Android游戲開發十日通(3)-創建第一個Android游戲

我們主要編寫的工程是test-gdx-game.其他兩個基本不東。
在工程下面創建相應的包,包括controller,model,screens,view.

這里用到了一些MVC的知識,簡單提一下:
MVC模式的目的是實現一種動態的程序設計,使后續對程序的修改和擴展簡化,并且使程序某一部分的重復利用成為可能。除此之外,此模式通過對復雜度的簡化,使程序結構更加直觀。軟件系統通過對自身基本部分分離的同時也賦予了各個基本部分應有的功能。專業人員可以通過自身的專長分組:
(控制器Controller)- 負責轉發請求,對請求進行處理。
(視圖View) - 界面設計人員進行圖形界面設計。
(模型Model) - 程序員編寫程序應有的功能(實現算法等等)、數據庫專家進行數據管理和數據庫設計(可以實現具體的功能)。


編碼

model
這里有三個model需要創建-Block(磚塊),Bob(人物),World(世界)。

Block.java
package com.me.testgdxgame.model;  import com.badlogic.gdx.math.Rectangle; import com.badlogic.gdx.math.Vector2;  public class Block {  	public static final float SIZE = 1f; 	 	Vector2 	position = new Vector2(); 	Rectangle 	bounds = new Rectangle(); 	 	public Block(Vector2 pos) { 		this.position = pos; 		this.bounds.setX(pos.x); 		this.bounds.setY(pos.y); 		this.bounds.width = SIZE; 		this.bounds.height = SIZE; 	}  	public Vector2 getPosition() { 		return position; 	}  	public Rectangle getBounds() { 		return bounds; 	} }



Vector2是libgdx中的二維向量類。bounds用于后面的碰撞檢測。

Bob.java
package com.me.testgdxgame.model;  import com.badlogic.gdx.math.Rectangle; import com.badlogic.gdx.math.Vector2;  public class Bob {  	public enum State { 		IDLE, WALKING, JUMPING, DYING 	}  	public static final float SPEED = 4f;	// unit per second 	static final float JUMP_VELOCITY = 1f; 	public static final float SIZE = 0.5f; // half a unit  	Vector2 	position = new Vector2(); 	Vector2 	acceleration = new Vector2(); 	Vector2 	velocity = new Vector2(); 	Rectangle 	bounds = new Rectangle(); 	State		state = State.IDLE; 	boolean		facingLeft = true; 	float		stateTime = 0;  	public Bob(Vector2 position) { 		this.position = position; 		this.bounds.height = SIZE; 		this.bounds.width = SIZE; 	} 	public boolean isFacingLeft() { 		return facingLeft; 	} 	public void setFacingLeft(boolean facingLeft) { 		this.facingLeft = facingLeft; 	}  	public Vector2 getPosition() { 		return position; 	}  	public Vector2 getAcceleration() { 		return acceleration; 	}  	public Vector2 getVelocity() { 		return velocity; 	}  	public Rectangle getBounds() { 		return bounds; 	}  	public State getState() { 		return state; 	}  	public void setState(State newState) { 		this.state = newState; 	}  	public float getStateTime() { 		return stateTime; 	}   	public void update(float delta) { 		//stateTime += delta; 		//position.add(velocity.tmp().mul(delta));  		position.add(velocity.cpy().mul(delta)); 	} } 

Bob就有很多屬性了,速度,位置什么的,代碼也很簡單。

World.java
package com.me.testgdxgame.model;  import java.util.ArrayList;  import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.Array;  public class World {  	/** The blocks making up the world **/ 	ArrayList<Block> blocks = new ArrayList(); 	/** Our player controlled hero **/ 	Bob bob;  	// Getters ----------- 	public ArrayList<Block>  getBlocks() { 		return blocks; 	} 	public Bob getBob() { 		return bob; 	} 	// --------------------  	public World() { 		createDemoWorld(); 	}  	private void createDemoWorld() { 		bob = new Bob(new Vector2(7, 2));  		for (int i = 0; i < 10; i++) { 			 	 			blocks.add(new Block(new Vector2(i, 0)));  			blocks.add(new Block(new Vector2(i, 6))); 	 			if (i > 2) 				blocks.add(new Block(new Vector2(i, 1))); 		} 		blocks.add(new Block(new Vector2(9, 2))); 		blocks.add(new Block(new Vector2(9, 3))); 		blocks.add(new Block(new Vector2(9, 4))); 		blocks.add(new Block(new Vector2(9, 5)));  		blocks.add(new Block(new Vector2(6, 3))); 		blocks.add(new Block(new Vector2(6, 4))); 		blocks.add(new Block(new Vector2(6, 5))); 	} } 

World中包括了地圖和人物。

View
view中的類主要負責渲染。
首先在項目中添加兩個紋理。
Android游戲開發十日通(3)-創建第一個Android游戲Android游戲開發十日通(3)-創建第一個Android游戲
放到android工程的asset/data下面就可以了。
注意:紋理貼圖的長寬像素一定是2的冪,比如64×64,128×128..否則無法加載。官方解釋是opengl的一個bug,無法解決。

package com.me.testgdxgame.view;   import com.me.testgdxgame.*; import com.me.testgdxgame.model.Block; import com.me.testgdxgame.model.Bob; import com.me.testgdxgame.model.World; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.GL10; import com.badlogic.gdx.graphics.OrthographicCamera; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.graphics.glutils.ShapeRenderer; import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType; import com.badlogic.gdx.math.Rectangle;  public class WorldRenderer {  	private World world; 	private OrthographicCamera cam;  	private SpriteBatch spriteBatch; 	private boolean debug=false; 	private int width; 	private int height; 	private float ppuX; // pixels per unit on the X axis 	private float ppuY; // pixels per unit on the Y axis 	private static final float CAMERA_WIDTH = 10f; 	private static final float CAMERA_HEIGHT = 7f; 	/** Textures **/ 	private Texture bobTexture; 	private Texture blockTexture;    	/** for debug rendering **/ 	ShapeRenderer debugRenderer = new ShapeRenderer();  	public WorldRenderer(World world) { 		this.world = world; 		this.cam = new OrthographicCamera(10, 7); 		this.cam.position.set(5, 3.5f, 0); 		this.cam.update(); 		spriteBatch=new SpriteBatch(); 		loadTextures(); 	} 	public void setSize (int w, int h) { 		this.width = w; 		this.height = h; 		ppuX = (float)width / CAMERA_WIDTH; 		ppuY = (float)height / CAMERA_HEIGHT; 	}  	private void loadTextures(){ 		bobTexture=new Texture(Gdx.files.internal("data/bob_01.png")); 		blockTexture=new Texture(Gdx.files.internal("data/block.png")); 	}   	public void render() { 		spriteBatch.begin(); 		drawBlocks(); 		drawBob(); 		spriteBatch.end(); 		if(debug) drawDebug(); 	}  	private void  drawBlocks(){ 		for (Block block : world.getBlocks()) { 			spriteBatch.draw(blockTexture, block.getPosition().x * ppuX, block.getPosition().y * ppuY, Block.SIZE * ppuX, Block.SIZE * ppuY); 		} 	} 	private void drawBob(){ 		Bob bob = world.getBob(); 		spriteBatch.draw(bobTexture, bob.getPosition().x * ppuX, bob.getPosition().y * ppuY, Bob.SIZE * ppuX, Bob.SIZE * ppuY); 	}  	private void drawDebug(){ 		// render blocks 		debugRenderer.setProjectionMatrix(cam.combined); 		debugRenderer.begin(ShapeType.Rectangle); 		for (Block block : world.getBlocks()) { 			Rectangle rect = block.getBounds(); 			float x1 = block.getPosition().x + rect.x; 			float y1 = block.getPosition().y + rect.y; 			debugRenderer.setColor(new Color(1, 0, 0, 1)); 			debugRenderer.rect(x1, y1, rect.width, rect.height); 		} 		// render Bob  		Bob bob = world.getBob(); 		Rectangle rect = bob.getBounds(); 		float x1 = bob.getPosition().x + rect.x; 		float y1 = bob.getPosition().y + rect.y; 		debugRenderer.setColor(new Color(0, 1, 0, 1)); 		debugRenderer.rect(x1, y1, rect.width, rect.height); 		debugRenderer.end(); 	} } 

有幾個類簡單解釋一下:
OrthographicCamera:正交坐標系Camerta。用于設置攝像機。到后期需要將人固定在攝像機視口中間,跟隨人移動。
ShapeRenderer:用于繪制,包括紋理,線條,點,矩形等等。
SpriteBatch:負責加載,管理,繪制紋理。

這個類里面有個drawDebug()可以用于不添加紋理的時候繪制,繪制的結果如下:

Android游戲開發十日通(3)-創建第一個Android游戲

Controller
這個類用于處理輸入。
WorldController.java
package com.me.testgdxgame.controller;  import java.util.HashMap; import java.util.Map;  import com.me.testgdxgame.model.Bob; import com.me.testgdxgame.model.Bob.State; import com.me.testgdxgame.model.World;  public class WorldController { 	 	enum Keys{ 		LEFT,RIGHT,JUMP,FIRE 	} 	private World world; 	private Bob bob; 	 	static Map<Keys,Boolean> keys = new HashMap<WorldController.Keys,Boolean>(); 	static { 		keys.put(Keys.LEFT, false); 		keys.put(Keys.RIGHT, false); 		keys.put(Keys.JUMP, false); 		keys.put(Keys.FIRE, false); 	}; 	 	public WorldController(World w){ 		world=w; 		bob=world.getBob(); 	} 	 	//Key presses and touches 	public void leftPressed(){ 		keys.get(keys.put(Keys.LEFT, true)); 	} 	public void rightPressed() { 		keys.get(keys.put(Keys.RIGHT, true)); 	}  	public void jumpPressed() { 		keys.get(keys.put(Keys.JUMP, true)); 	}  	public void firePressed() { 		keys.get(keys.put(Keys.FIRE, false)); 	}  	public void leftReleased() { 		keys.get(keys.put(Keys.LEFT, false)); 	}  	public void rightReleased() { 		keys.get(keys.put(Keys.RIGHT, false)); 	}  	public void jumpReleased() { 		keys.get(keys.put(Keys.JUMP, false)); 	}  	public void fireReleased() { 		keys.get(keys.put(Keys.FIRE, false)); 	} 	 	public void update(float delta){ 		processInput(); 		bob.update(delta); 	} 	 	private void processInput(){ 		if(keys.get(Keys.LEFT)){ 			bob.setFacingLeft(true); 			bob.setState(State.WALKING); 			bob.getVelocity().x=-Bob.SPEED; 		} 		if (keys.get(Keys.RIGHT)) { 			// left is pressed 			bob.setFacingLeft(false); 			bob.setState(State.WALKING); 			bob.getVelocity().x = Bob.SPEED; 		} 		// need to check if both or none direction are pressed, then Bob is idle 		if ((keys.get(Keys.LEFT) && keys.get(Keys.RIGHT)) || 				(!keys.get(Keys.LEFT) && !(keys.get(Keys.RIGHT)))) { 			bob.setState(State.IDLE); 			// acceleration is 0 on the x 			bob.getAcceleration().x = 0; 			// horizontal speed is 0 			bob.getVelocity().x = 0; 		} 	} } 

屏幕
mvc都有了,接下來就可以屏幕了。
一個游戲通常有很多屏幕,歡迎屏幕,游戲屏幕,參數設置屏幕,游戲結束屏幕等等。
今天我們之做一個游戲屏幕。
在screens包里添加GameScreen類。
package com.me.testgdxgame.screens;   import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Input.Keys; import com.badlogic.gdx.InputProcessor; import com.badlogic.gdx.Screen; import com.badlogic.gdx.graphics.GL10; import com.me.testgdxgame.controller.WorldController; import com.me.testgdxgame.model.World; import com.me.testgdxgame.view.WorldRenderer;  public class GameScreen implements Screen ,InputProcessor{  	private WorldRenderer renderer; 	private World world; 	private WorldController controller; 	 	private int width, height;  	@Override 	public void render(float delta) { 		// TODO Auto-generated method stub 		 		Gdx.gl.glClearColor(0.1f, 0.1f, 0.1f, 1); 		Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT); 		 		controller.update(delta); 		renderer.render();  	}  	@Override 	public void resize(int width, int height) { 		// TODO Auto-generated method stub 		renderer.setSize(width, height); 		this.width=width; 		this.height=height; 	}  	@Override 	public void show() { 		// TODO Auto-generated method stub 		world = new World(); 		renderer = new WorldRenderer(world); 		controller=new WorldController(world); 		Gdx.input.setInputProcessor(this); 	}  	@Override 	public void hide() { 		// TODO Auto-generated method stub 		Gdx.input.setInputProcessor(null); 	}  	@Override 	public void pause() { 		// TODO Auto-generated method stub 	}  	@Override 	public void resume() { 		// TODO Auto-generated method stub 	}  	@Override 	public void dispose() { 		// TODO Auto-generated method stub 		Gdx.input.setInputProcessor(null); 	}  	@Override 	public boolean keyDown(int keycode) { 		// TODO Auto-generated method stub 		if (keycode == Keys.LEFT) 			controller.leftPressed(); 		if (keycode == Keys.RIGHT) 			controller.rightPressed(); 		if (keycode == Keys.Z) 			controller.jumpPressed(); 		if (keycode == Keys.X) 			controller.firePressed(); 		return true; 	}  	@Override 	public boolean keyUp(int keycode) { 		// TODO Auto-generated method stub 		if (keycode == Keys.LEFT) 			controller.leftReleased(); 		if (keycode == Keys.RIGHT) 			controller.rightReleased(); 		if (keycode == Keys.Z) 			controller.jumpReleased(); 		if (keycode == Keys.X) 			controller.fireReleased(); 		return true; 	}  	@Override 	public boolean keyTyped(char character) { 		// TODO Auto-generated method stub 		return false; 	}  	@Override 	public boolean touchDown(int x, int y, int pointer, int button) { 		// TODO Auto-generated method stub 		if (x < width / 2 && y > height / 2) { 			controller.leftPressed(); 		} 		if (x > width / 2 && y > height / 2) { 			controller.rightPressed(); 		} 		return false; 	}  	@Override 	public boolean touchUp(int x, int y, int pointer, int button) { 		// TODO Auto-generated method stub 		if (x < width / 2 && y > height / 2) { 			controller.leftReleased(); 		} 		if (x > width / 2 && y > height / 2) { 			controller.rightReleased(); 		} 		return true; 	}  	@Override 	public boolean touchDragged(int screenX, int screenY, int pointer) { 		// TODO Auto-generated method stub 		return false; 	}  	@Override 	public boolean mouseMoved(int screenX, int screenY) { 		// TODO Auto-generated method stub 		return false; 	}  	@Override 	public boolean scrolled(int amount) { 		// TODO Auto-generated method stub 		return false; 	} } 

這個類實現了Screen ,InputProcessor接口。
InputProcessor用于接受觸控事件和按鍵事件。

部署

desktop版本的項目基本不用修改。main函數如下:
public class Main { 	public static void main(String[] args) { 		LwjglApplicationConfiguration cfg = new LwjglApplicationConfiguration(); 		cfg.title = "test-gdx-game"; 		cfg.useGL20 = false; 		cfg.width = 1024; 		cfg.height = 600; 		 		new LwjglApplication(new TestGdxGame(), cfg); 	} }

Main.java上右擊->run as->java application.

android版本修改一下MainActiviy:
public class MainActivity extends AndroidApplication {     @Override     public void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);                  AndroidApplicationConfiguration cfg = new AndroidApplicationConfiguration();         cfg.useGL20 = false;                  initialize(new TestGdxGame(), cfg);     } }

run as->android application.

總結

到現在,舞臺和代碼框架已經搭建好了,后面還可以添加下面的東西:

.地行碰撞
.動畫
.高等級的camera(視角可以不斷變化)
.音效
.改進的輸入
.更多的GameScreen

一起期待下一篇教程。

×××

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

德钦县| 宜川县| 巫溪县| 鸡泽县| 齐齐哈尔市| 阳新县| 岢岚县| 巩留县| 洞口县| 高碑店市| 城口县| 苏尼特右旗| 永吉县| 田林县| 乌拉特前旗| 乌鲁木齐市| 北流市| 凤翔县| 天台县| 仁怀市| 洛浦县| 图木舒克市| 曲沃县| 怀仁县| 康马县| 正定县| 隆化县| 阿图什市| 伊宁县| 曲麻莱县| 麟游县| 惠水县| 珠海市| 扶余县| 万山特区| 雷波县| 金川县| 大余县| 黑河市| 安多县| 广昌县|