android 2D游戏开发,引擎设计(三) 实验脚本编写与纸娃娃系统
生活随笔
收集整理的這篇文章主要介紹了
android 2D游戏开发,引擎设计(三) 实验脚本编写与纸娃娃系统
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
2D紙娃娃
在以前沒有采用紙娃娃系統的游戲中,游戲角色的所有外觀都是游戲美工預先制作好的,因此數量有限,且占用較多資源(內存,硬盤空間),比如為了實現同一角色拿著不同武器奔跑的圖像,開發者不得不繪制兩套奔跑圖,分別加上不同的武器。而實際上,變化的只是武器,這樣多的一組奔跑圖像就是多余的。而紙娃娃系統就是針對此設計的。 在紙娃娃系統中,角色的每個動作,每套服裝,武器,都只有一套,而且是獨立的。引擎可以根據不同的需要,臨時將幾組圖像拼裝到一起,進而形成變化豐富的角色外觀。例如同時角色奔跑,可以在手部繪制武器A,也可以繪制武器B。 為了豐富角色的動作,2D紙娃娃有時也將角色的頭,身,手,腳等部位的動作都分開繪制,在2D圖像基礎上展示了更多變的角色動作。 2D紙娃娃系統比起普通游戲的最大優勢就在于,數量相同的角色外觀下,占用更少的資源,角色的外觀變化即時展示。而這樣的系統在編程稍稍復雜。
紙娃娃系統并不復雜,它的難度如以下這個問題。
桌子上有一個碗,碗里面有個杯子,移動了一下桌子,問杯子的坐標? ?(已知桌子的坐標,已知碗在桌子中的坐標)。
為了實現紙娃娃這種嵌套系統,我們需要引入相對坐標和絕對坐標的概念。
上回說的接口扮演者Act 和類演員Actor,我們添加新方法
/**獲得絕對坐標X*/public double getAbsoluteX();/**獲得絕對坐標Y*/public double getAbsoluteY();/**獲得相對于容器坐標X*/public double getX() ;/**設置相對于容器坐標X*/public void setX(double x);/**獲得相對于容器坐標Y*/public double getY();/**設置相對于容器坐標Y*/public void setY(double y)//獲得絕對坐標方法
public double getAbsoluteX() {//如果容器不為空, 絕對坐標X=容器的絕對坐標X加相對坐標Xreturn getActParent()== null ? getX() : getActParent().getAbsoluteX() + getX();}public double getAbsoluteY() {//如果容器不為空, 絕對坐標Y=容器的絕對坐標Y加相對坐標Yreturn getActParent() == null ? getY() : getActParent().getAbsoluteY() + getY();}繪制內部子扮演者方法
/** 繪制當前 */public void draw(GameCanvas canvas, IAct thisAct) {if (getModel() != null)getModel().draw(canvas, thisAct);drawChild(canvas);};//繪制子扮演者public void drawChild(GameCanvas canvas) {if (childList != null) {Iterator<IAct> it = childList.iterator();while (it.hasNext()) {IAct act = it.next();act.draw(canvas, act);if (act.getScript() != null)act.getScript().timeScript(act.getGameStage(), canvas, act);}}}package game.engines.inteface;import java.util.HashMap;import game.engines.Direction; import game.engines.GameCanvas; import game.engines.GameStage; import game.engines.Model; import game.engines.Script;/*** 扮演者*/ public interface IAct {/**將本身作為容器添加扮演者 被添加的扮演者絕對坐標將以容器相對坐標來計算*/public void addAct(IAct act);/**移除扮演者*/public void removeAct(IAct act);/**獲得該扮演者上層容器*/public IAct getActParent();/**獲得該扮演者上層容器*/public void setActParent(IAct act);/**繪制該版本扮演者* 該方法同時* @see drawChild* */public void draw(GameCanvas canvas,IAct act);/**繪制扮演者容器中的子扮演者*/public void drawChild(GameCanvas canvas);/**設置扮演者腳本*/public void setScript(Script script);/**獲得扮演者腳本*/public Script getScript();/**獲得扮演者腳本*/public HashMap<String,Object> getAttributes();/**獲得設置屬性集*/public void setAttributes(HashMap<String, Object> attributes);/**獲得設置屬性*/public void setAttributes(String key,Object value);/**獲得絕對坐標X*/public double getAbsoluteX();/**獲得絕對坐標Y*/public double getAbsoluteY();/**獲得相對于容器坐標X*/public double getX() ;/**設置相對于容器坐標X*/public void setX(double x);/**獲得相對于容器坐標Y*/public double getY();/**設置相對于容器坐標Y*/public void setY(double y);/**獲得寬度屬性*/public int getWidth();/**設置寬度屬性*/public void setWidth(int width) ;/**獲得高度屬性*/public int getHeight();/**設置高度屬性*/public void setHeight(int height);/**獲得移動速度*/public double getMove();/**設置移動速度*/public void setMove(double move);/**獲得造型*/public Model getModel();/**設置造型*/public void setModel(Model model);/**設置方向*/public void setDirection(Direction direction);/**獲得方向*/public Direction getDirection();/**獲得所在舞臺*/public GameStage getGameStage();/**設置所在舞臺*/public void setGameStage(GameStage stage);}
利用紙娃娃系統來編寫的太陽系。如圖 太陽(黃色) 地球(青色) ?月球(藍色) 衛星(灰色)?
如果將太陽系看作為一個整體你可以想象這用java需要多少行代碼。
實際上只需要很少量的代碼就足以完成它。
代碼示例
package game.demo;import android.graphics.Color; import game.engines.Actor; import game.engines.GameCanvas; import game.engines.GameStage; import game.engines.Model; import game.engines.Script; import game.engines.action.CircleMoveScript;import game.engines.inteface.IAct;/*** 游戲劇情腳本*/ public class MyGameScript extends Script {/*** 時間腳本* */public void timeScript(GameStage stage, GameCanvas canvas, IAct act) {//新建一只精靈Actor sun= new Actor();//新建一個造型.Model circle = new Model() {@Overridepublic void draw(GameCanvas canvas, IAct thisAct) {try {//獲得顏色屬性int color = (Integer) thisAct.getAttributes().get("Color");canvas.getPaint().setColor(color);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}// paint.setStyle(Paint.Style.STROKE);//在絕對坐標上繪制一個圓canvas.drawCircle(thisAct.getAbsoluteX(),thisAct.getAbsoluteY(), thisAct.getHeight(),canvas.getPaint());}};//設置太陽的造型是圓sun.setModel(circle);//設置太陽的屬性 Color 黃色sun.setAttributes("Color", Color.YELLOW);sun.setX(250);sun.setY(150);sun.setWidth(25);sun.setHeight(25);//設置腳本為圓運動 半徑25 角度從100開始 速率10毫秒內0.005轉sun.setScript(new CircleMoveScript(25, 100, 0.005));//新建地球Actor earth = new Actor();earth.setAttributes("Color", Color.CYAN);earth.setModel(circle);earth.setWidth(15);earth.setHeight(15);earth.setScript(new CircleMoveScript(130, 0, 0.01));//Actor moon = new Actor();moon.setAttributes("Color", Color.BLUE);moon.setModel(circle);moon.setWidth(5);moon.setHeight(5);moon.setScript(new CircleMoveScript(35, 0, 0.04));Actor star = new Actor();star.setAttributes("Color", Color.GRAY);star.setModel(circle);star.setWidth(2);star.setHeight(2);star.setScript(new CircleMoveScript(10, 0, 0.1));//將月亮和衛星組合一個系統moon.addAct(star);//將地球和月亮組合一個系統earth.addAct(moon);//將太陽和地球組合一個系統sun.addAct(earth);// 獲得腳本的扮演者當前的舞臺的場景 添加扮演者act.getGameStage().getScreen().addAct(sun);// 因為這個腳本只需要執行一次 所以執行完移除腳本act.getGameStage().setScript(null);}
*這時會發現Actor本身能代替Layer畫布的功能,所以Layer可以刪除今后由Actor任意實現多層嵌套紙娃娃系統的功能。
腳本引擎本身也是可以嵌套,重用性很強。我們的開發工作會越來越輕松。足夠的靈活將帶給我們所需要的強大的功能。
舉個例子將來我們可以實現配置文件,
比如飛機墜落腳本,你能想象它的運動方式
飛機墜落.txt
[飛機]
x=0
y=0
width=100
height=100
script=圓周運動,向右運動,向下運動
總結
以上是生活随笔為你收集整理的android 2D游戏开发,引擎设计(三) 实验脚本编写与纸娃娃系统的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: VC 6中使用不同调用规范的函数在符号文
- 下一篇: 湖大离散数学实验代码汇总