日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > windows >内容正文

windows

android 2D游戏开发,引擎设计(三) 实验脚本编写与纸娃娃系统

發(fā)布時(shí)間:2023/12/20 windows 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android 2D游戏开发,引擎设计(三) 实验脚本编写与纸娃娃系统 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

2D紙娃娃

在以前沒(méi)有采用紙娃娃系統(tǒng)的游戲中,游戲角色的所有外觀都是游戲美工預(yù)先制作好的,因此數(shù)量有限,且占用較多資源(內(nèi)存,硬盤空間),比如為了實(shí)現(xiàn)同一角色拿著不同武器奔跑的圖像,開(kāi)發(fā)者不得不繪制兩套奔跑圖,分別加上不同的武器。而實(shí)際上,變化的只是武器,這樣多的一組奔跑圖像就是多余的。而紙娃娃系統(tǒng)就是針對(duì)此設(shè)計(jì)的。 在紙娃娃系統(tǒng)中,角色的每個(gè)動(dòng)作,每套服裝,武器,都只有一套,而且是獨(dú)立的。引擎可以根據(jù)不同的需要,臨時(shí)將幾組圖像拼裝到一起,進(jìn)而形成變化豐富的角色外觀。例如同時(shí)角色奔跑,可以在手部繪制武器A,也可以繪制武器B。 為了豐富角色的動(dòng)作,2D紙娃娃有時(shí)也將角色的頭,身,手,腳等部位的動(dòng)作都分開(kāi)繪制,在2D圖像基礎(chǔ)上展示了更多變的角色動(dòng)作。 2D紙娃娃系統(tǒng)比起普通游戲的最大優(yōu)勢(shì)就在于,數(shù)量相同的角色外觀下,占用更少的資源,角色的外觀變化即時(shí)展示。而這樣的系統(tǒng)在編程稍稍復(fù)雜。


紙娃娃系統(tǒng)并不復(fù)雜,它的難度如以下這個(gè)問(wèn)題。

桌子上有一個(gè)碗,碗里面有個(gè)杯子,移動(dòng)了一下桌子,問(wèn)杯子的坐標(biāo)? ?(已知桌子的坐標(biāo),已知碗在桌子中的坐標(biāo))。

為了實(shí)現(xiàn)紙娃娃這種嵌套系統(tǒng),我們需要引入相對(duì)坐標(biāo)和絕對(duì)坐標(biāo)的概念。


上回說(shuō)的接口扮演者Act 和類演員Actor,我們添加新方法

/**獲得絕對(duì)坐標(biāo)X*/public double getAbsoluteX();/**獲得絕對(duì)坐標(biāo)Y*/public double getAbsoluteY();/**獲得相對(duì)于容器坐標(biāo)X*/public double getX() ;/**設(shè)置相對(duì)于容器坐標(biāo)X*/public void setX(double x);/**獲得相對(duì)于容器坐標(biāo)Y*/public double getY();/**設(shè)置相對(duì)于容器坐標(biāo)Y*/public void setY(double y)

//獲得絕對(duì)坐標(biāo)方法

public double getAbsoluteX() {//如果容器不為空, 絕對(duì)坐標(biāo)X=容器的絕對(duì)坐標(biāo)X加相對(duì)坐標(biāo)Xreturn getActParent()== null ? getX() : getActParent().getAbsoluteX() + getX();}public double getAbsoluteY() {//如果容器不為空, 絕對(duì)坐標(biāo)Y=容器的絕對(duì)坐標(biāo)Y加相對(duì)坐標(biāo)Yreturn getActParent() == null ? getY() : getActParent().getAbsoluteY() + getY();}

繪制內(nèi)部子扮演者方法

/** 繪制當(dāng)前 */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 {/**將本身作為容器添加扮演者 被添加的扮演者絕對(duì)坐標(biāo)將以容器相對(duì)坐標(biāo)來(lái)計(jì)算*/public void addAct(IAct act);/**移除扮演者*/public void removeAct(IAct act);/**獲得該扮演者上層容器*/public IAct getActParent();/**獲得該扮演者上層容器*/public void setActParent(IAct act);/**繪制該版本扮演者* 該方法同時(shí)* @see drawChild* */public void draw(GameCanvas canvas,IAct act);/**繪制扮演者容器中的子扮演者*/public void drawChild(GameCanvas canvas);/**設(shè)置扮演者腳本*/public void setScript(Script script);/**獲得扮演者腳本*/public Script getScript();/**獲得扮演者腳本*/public HashMap<String,Object> getAttributes();/**獲得設(shè)置屬性集*/public void setAttributes(HashMap<String, Object> attributes);/**獲得設(shè)置屬性*/public void setAttributes(String key,Object value);/**獲得絕對(duì)坐標(biāo)X*/public double getAbsoluteX();/**獲得絕對(duì)坐標(biāo)Y*/public double getAbsoluteY();/**獲得相對(duì)于容器坐標(biāo)X*/public double getX() ;/**設(shè)置相對(duì)于容器坐標(biāo)X*/public void setX(double x);/**獲得相對(duì)于容器坐標(biāo)Y*/public double getY();/**設(shè)置相對(duì)于容器坐標(biāo)Y*/public void setY(double y);/**獲得寬度屬性*/public int getWidth();/**設(shè)置寬度屬性*/public void setWidth(int width) ;/**獲得高度屬性*/public int getHeight();/**設(shè)置高度屬性*/public void setHeight(int height);/**獲得移動(dòng)速度*/public double getMove();/**設(shè)置移動(dòng)速度*/public void setMove(double move);/**獲得造型*/public Model getModel();/**設(shè)置造型*/public void setModel(Model model);/**設(shè)置方向*/public void setDirection(Direction direction);/**獲得方向*/public Direction getDirection();/**獲得所在舞臺(tái)*/public GameStage getGameStage();/**設(shè)置所在舞臺(tái)*/public void setGameStage(GameStage stage);}



利用紙娃娃系統(tǒng)來(lái)編寫的太陽(yáng)系。如圖 太陽(yáng)(黃色) 地球(青色) ?月球(藍(lán)色) 衛(wèi)星(灰色)?

如果將太陽(yáng)系看作為一個(gè)整體你可以想象這用java需要多少行代碼。

實(shí)際上只需要很少量的代碼就足以完成它。


代碼示例

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 {/*** 時(shí)間腳本* */public void timeScript(GameStage stage, GameCanvas canvas, IAct act) {//新建一只精靈Actor sun= new Actor();//新建一個(gè)造型.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);//在絕對(duì)坐標(biāo)上繪制一個(gè)圓canvas.drawCircle(thisAct.getAbsoluteX(),thisAct.getAbsoluteY(), thisAct.getHeight(),canvas.getPaint());}};//設(shè)置太陽(yáng)的造型是圓sun.setModel(circle);//設(shè)置太陽(yáng)的屬性 Color 黃色sun.setAttributes("Color", Color.YELLOW);sun.setX(250);sun.setY(150);sun.setWidth(25);sun.setHeight(25);//設(shè)置腳本為圓運(yùn)動(dòng) 半徑25 角度從100開(kāi)始 速率10毫秒內(nèi)0.005轉(zhuǎn)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));//將月亮和衛(wèi)星組合一個(gè)系統(tǒng)moon.addAct(star);//將地球和月亮組合一個(gè)系統(tǒng)earth.addAct(moon);//將太陽(yáng)和地球組合一個(gè)系統(tǒng)sun.addAct(earth);// 獲得腳本的扮演者當(dāng)前的舞臺(tái)的場(chǎng)景 添加扮演者act.getGameStage().getScreen().addAct(sun);// 因?yàn)檫@個(gè)腳本只需要執(zhí)行一次 所以執(zhí)行完移除腳本act.getGameStage().setScript(null);}


package game.engines.action; import game.engines.GameCanvas; import game.engines.GameStage; import game.engines.Script; import game.engines.inteface.IAct;/*** 圓周運(yùn)動(dòng)*/ public class CircleMoveScript extends Script {double cx;double cy;double radius = 70;double speed;boolean init = false;double step = 0;public CircleMoveScript(double radius, double step,double speed) {super();this.radius = radius;this.step = step;this.speed=speed;}public void timeScript(GameStage stage,GameCanvas canvas,IAct a) {//初始化圓心if (!init) {cx = a.getX();cy = a.getY();init = true;}double x;double y;//每次角度+速率step += speed;//圓的參數(shù)方程x = cx + radius * Math.cos(step);y = cy + radius * Math.sin(step);a.setX(x);a.setY(y);} }


*這時(shí)會(huì)發(fā)現(xiàn)Actor本身能代替Layer畫布的功能,所以Layer可以刪除今后由Actor任意實(shí)現(xiàn)多層嵌套紙娃娃系統(tǒng)的功能。

腳本引擎本身也是可以嵌套,重用性很強(qiáng)。我們的開(kāi)發(fā)工作會(huì)越來(lái)越輕松。足夠的靈活將帶給我們所需要的強(qiáng)大的功能。


舉個(gè)例子將來(lái)我們可以實(shí)現(xiàn)配置文件,

比如飛機(jī)墜落腳本,你能想象它的運(yùn)動(dòng)方式

飛機(jī)墜落.txt

[飛機(jī)]

x=0

y=0

width=100

height=100

script=圓周運(yùn)動(dòng),向右運(yùn)動(dòng),向下運(yùn)動(dòng)




總結(jié)

以上是生活随笔為你收集整理的android 2D游戏开发,引擎设计(三) 实验脚本编写与纸娃娃系统的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。