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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

libgdx游戏引擎开发笔记(十三)SuperJumper游戏例子的讲解(篇七)----各个物体的创建及其碰撞检测...

發布時間:2025/3/8 编程问答 12 豆豆
生活随笔 收集整理的這篇文章主要介紹了 libgdx游戏引擎开发笔记(十三)SuperJumper游戏例子的讲解(篇七)----各个物体的创建及其碰撞检测... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? ?接著上一篇,我們完成后續的掃尾工作:游戲中個物體創建及其碰撞檢測,分數保存,音效處理。


1.World類:(加入所有物體,及其碰撞檢測,代碼里有詳細注解)

package com.zhf.mylibgdx; import java.util.ArrayList; import java.util.List; import java.util.Random; import com.badlogic.gdx.math.Vector2; /*** 統一管理世界中各個部分* @author ZHF**/ public class World {/**世界監聽器接口**/public interface WorldListener {//跳躍public void jump ();//高跳public void highJump ();//碰撞public void hit ();//收集金幣public void coin ();}//寬和高public static final float WORLD_WIDTH = 10;public static final float WORLD_HEIGHT = 15 * 20;//狀態public static final int WORLD_STATE_RUNNING = 0; //運行public static final int WORLD_STATE_NEXT_LEVEL = 1; //下一關public static final int WORLD_STATE_GAME_OVER = 2; //游戲結束//世界監聽器public WorldListener listener;//重力public static final Vector2 gravity = new Vector2(0, -12);//隨機數public Random rand;public float heightSoFar; //public int score;public int state;//游戲中物體public final List<Platform> platforms; //跳板public final Bob bob; //主角public final List<Spring> springs; //彈簧public final List<Squirrel> squirrels; //會飛的松鼠public final List<Coin> coins; //金幣public Castle castle; //城堡public World(WorldListener listener) {this.listener = listener;//初始化游戲中的物體this.bob = new Bob(5, 1);this.platforms = new ArrayList<Platform>();this.springs = new ArrayList<Spring>();this.squirrels = new ArrayList<Squirrel>();this.coins = new ArrayList<Coin>();rand = new Random();generateLevel(); //生成關卡中除了Bob外所有的物體}/**生成關卡中除了Bob外所有的物體**/private void generateLevel() {float y = Platform.PLATFORM_HEIGHT / 2;float maxJumpHeight = Bob.BOB_JUMP_VELOCITY * Bob.BOB_JUMP_VELOCITY / (2 * -gravity.y);while (y < WORLD_HEIGHT - WORLD_WIDTH / 2) {int type = rand.nextFloat() > 0.8f ? Platform.PLATFORM_TYPE_MOVING : Platform.PLATFORM_TYPE_STATIC;float x = rand.nextFloat() * (WORLD_WIDTH - Platform.PLATFORM_WIDTH) + Platform.PLATFORM_WIDTH / 2;//跳板的位置Platform platform = new Platform(type, x, y);platforms.add(platform);//彈簧的位置if (rand.nextFloat() > 0.9f && type != Platform.PLATFORM_TYPE_MOVING) {Spring spring = new Spring(platform.position.x, platform.position.y + Platform.PLATFORM_HEIGHT / 2+ Spring.SPRING_HEIGHT / 2);springs.add(spring);}//松鼠的位置if (y > WORLD_HEIGHT / 3 && rand.nextFloat() > 0.8f) {Squirrel squirrel = new Squirrel(platform.position.x + rand.nextFloat(), platform.position.y+ Squirrel.SQUIRREL_HEIGHT + rand.nextFloat() * 2);squirrels.add(squirrel);}//金幣的位置if (rand.nextFloat() > 0.6f) {Coin coin = new Coin(platform.position.x + rand.nextFloat(), platform.position.y + Coin.COIN_HEIGHT+ rand.nextFloat() * 3);coins.add(coin);}//游戲中的物體的位置根據跳板的位置來確定y += (maxJumpHeight - 0.5f);y -= rand.nextFloat() * (maxJumpHeight / 3);}//城堡的位置是確定的castle = new Castle(WORLD_WIDTH / 2, y);}/**刷新界面**/public void update(float deltaTime, float accelX) {updateBob(deltaTime, accelX); //刷新主角updatePlatforms(deltaTime); //刷新跳板updateSquirrels(deltaTime); //刷新松鼠updateCoins(deltaTime); //刷新金幣if (bob.state != Bob.BOB_STATE_HIT) checkCollisions();//游戲結束判斷checkGameOver();}/**碰撞檢測**/private void checkCollisions() {// TODO Auto-generated method stubcheckPlatformCollisions(); //跳板的碰撞checkSquirrelCollisions(); //松鼠的碰撞checkItemCollisions(); //金幣和彈簧的碰撞checkCastleCollisions(); //城堡的碰撞}/**跳板碰撞**/private void checkPlatformCollisions() {if (bob.velocity.y > 0) return;int len = platforms.size();for (int i = 0; i < len; i++) {Platform platform = platforms.get(i);if (bob.position.y > platform.position.y) {//調用工具類中矩形塊碰撞檢測if (OverlapTester.overlapRectangles(bob.bounds, platform.bounds)) {bob.hitPlatform();listener.jump();if (rand.nextFloat() > 0.5f) {platform.pulverize();}break;}}}}/**松鼠碰撞**/private void checkSquirrelCollisions () {int len = squirrels.size();for (int i = 0; i < len; i++) {Squirrel squirrel = squirrels.get(i);if (OverlapTester.overlapRectangles(squirrel.bounds, bob.bounds)) {bob.hitSquirrel();listener.hit();}}}/**金幣和彈簧碰撞**/private void checkItemCollisions () {int len = coins.size();for (int i = 0; i < len; i++) {Coin coin = coins.get(i);if (OverlapTester.overlapRectangles(bob.bounds, coin.bounds)) {coins.remove(coin);len = coins.size();listener.coin();score += Coin.COIN_SCORE; //加分}}if (bob.velocity.y > 0) return; //若是上升狀態不去考慮碰撞檢測len = springs.size();for (int i = 0; i < len; i++) {Spring spring = springs.get(i);if (bob.position.y > spring.position.y) {//彈簧的碰撞檢測if (OverlapTester.overlapRectangles(bob.bounds, spring.bounds)) {bob.hitSpring();listener.highJump();}}}}/**城堡的碰撞**/private void checkCastleCollisions () {if (OverlapTester.overlapRectangles(castle.bounds, bob.bounds)) {state = WORLD_STATE_NEXT_LEVEL;}}/**刷新Bob**/private void updateBob(float deltaTime, float accelX) {//碰撞跳板if (bob.state != Bob.BOB_STATE_HIT && bob.position.y <= 0.5f) bob.hitPlatform();//主角x軸方向移動的速度if (bob.state != Bob.BOB_STATE_HIT) bob.velocity.x = -accelX / 10 * Bob.BOB_MOVE_VELOCITY;bob.update(deltaTime);//豎直最大高度heightSoFar = Math.max(bob.position.y, heightSoFar);}/**刷新跳板**/private void updatePlatforms(float deltaTime) {int len = platforms.size();for (int i = 0; i < len; i++) {Platform platform = platforms.get(i);//取出集合中的跳板對象,調用其自身的刷新方法platform.update(deltaTime);//若狀態為破碎狀態,將該跳板對象移除出去if (platform.state == Platform.PLATFORM_STATE_PULVERIZING && platform.stateTime > Platform.PLATFORM_PULVERIZE_TIME) {platforms.remove(platform);len = platforms.size();}}}/**刷新松鼠**/private void updateSquirrels (float deltaTime) {int len = squirrels.size();for (int i = 0; i < len; i++) {Squirrel squirrel = squirrels.get(i);squirrel.update(deltaTime);}}/**刷新金幣**/private void updateCoins (float deltaTime) {int len = coins.size();for (int i = 0; i < len; i++) {Coin coin = coins.get(i);coin.update(deltaTime);}}/**游戲結束判斷**/private void checkGameOver () {//目前的Bob的高度小于場景的高度if (heightSoFar - 7.5f > bob.position.y) {state = WORLD_STATE_GAME_OVER;}} }


? ? ? ?看著代碼挺多,其實就是一個update()和checkCollisions(),還有重要的generateLevel()。接下來就是渲染WorldRenderer類中繪制各個物體


/**渲染游戲中各種物體(Bob,跳板,松鼠,彈簧,城堡,金幣)**/private void renderObjects() {batch.enableBlending();batch.begin();renderPlatforms(); //繪制跳板renderBob(); //繪制主角renderItems(); //繪制金幣和彈簧renderSquirrels(); //繪制松鼠renderCastle(); //繪制城堡batch.end();}

? ?

? ?由于代碼過多,這里就不一一貼出來了,大家可以自行參考源碼,有注解的哦!

既然添加了游戲中的物體,那自然又得在Asset中加載資源

聲明:

//游戲中各種物體public static TextureRegion platform; //跳板public static Animation brakingPlatform; //破碎的跳板(動畫)//主角public static Animation bobJump; //跳躍(動畫)public static Animation bobFall; //下落(動畫)public static TextureRegion bobHit; //碰撞圖片public static TextureRegion spring; //彈簧public static TextureRegion castle; //城堡public static Animation coinAnim; //金幣 (動畫)public static Animation squirrelFly; //飛著的松鼠 (動畫)

實例化:

//游戲中各個物體platform = new TextureRegion(items, 64, 160, 64, 16); //跳板brakingPlatform = new Animation(0.2f, new TextureRegion(items, 64, 160, 64, 16), new TextureRegion(items, 64, 176, 64, 16),new TextureRegion(items, 64, 192, 64, 16), new TextureRegion(items, 64, 208, 64, 16));//破碎的跳板spring = new TextureRegion(items, 128, 0, 32, 32); //彈簧castle = new TextureRegion(items, 128, 64, 64, 64); //城堡coinAnim = new Animation(0.2f, new TextureRegion(items, 128, 32, 32, 32), new TextureRegion(items, 160, 32, 32, 32),new TextureRegion(items, 192, 32, 32, 32), new TextureRegion(items, 160, 32, 32, 32)); //金幣squirrelFly = new Animation(0.2f, new TextureRegion(items, 0, 160, 32, 32), new TextureRegion(items, 32, 160, 32, 32)); //飛著的松鼠//主角bobJump = new Animation(0.2f, new TextureRegion(items, 0, 128, 32, 32), new TextureRegion(items, 32, 128, 32, 32));bobFall = new Animation(0.2f, new TextureRegion(items, 64, 128, 32, 32), new TextureRegion(items, 96, 128, 32, 32));bobHit = new TextureRegion(items, 128, 128, 32, 32);

? ?運行一下代碼,我們發現,我們操作者主角向上移動,會遇到彈簧,會破碎的跳板,飛著的松鼠,金幣,一切都正常的運行著! 仔細一看,加上金幣后分數值沒有改變哦!當然還有死亡的判斷,音效的加入等等。

效果圖:


在此先做一個代碼版本,方便初學者能夠清楚的了解代碼

×××:http://down.51cto.com/data/897211


下面我們來完成分值的計算:


在GameScreen中:

/**游戲運行狀態**/private void updateRunning (float deltaTime) {if (Gdx.input.justTouched()) {guiCam.unproject(touchPoint.set(Gdx.input.getX(), Gdx.input.getY(), 0));//點擊暫停if (OverlapTester.pointInRectangle(pauseBounds, touchPoint.x, touchPoint.y)) {Assets.playSound(Assets.clickSound);state = GAME_PAUSED;return;}}ApplicationType appType = Gdx.app.getType();// should work also with Gdx.input.isPeripheralAvailable(Peripheral.Accelerometer)if (appType == ApplicationType.Android || appType == ApplicationType.iOS) {world.update(deltaTime, Gdx.input.getAccelerometerX());} else {float accel = 0;if (Gdx.input.isKeyPressed(Keys.DPAD_LEFT)) accel = 5f;if (Gdx.input.isKeyPressed(Keys.DPAD_RIGHT)) accel = -5f;world.update(deltaTime, accel);}//當前分數(變化)if (world.score != lastScore) {lastScore = world.score;scoreString = "SCORE: " + lastScore;}//本關結束if (world.state == World.WORLD_STATE_NEXT_LEVEL) {state = GAME_LEVEL_END;}//游戲結束,分值計算if (world.state == World.WORLD_STATE_GAME_OVER) {state = GAME_OVER;if (lastScore >= Settings.highscores[4])scoreString = "NEW HIGHSCORE: " + lastScore;elsescoreString = "SCORE: " + lastScore;//獲取最后分數Settings.addScore(lastScore);//保存分數Settings.save();}}

? ?這里我們每次碰到金幣就會加上10分,到游戲結束后,將最終得分保存起來,同時更新排行榜。

Settings:

package com.zhf.mylibgdx; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import com.badlogic.gdx.Gdx; /*** 設置類:三個方法: 1.load()讀取聲音開關和最高分. 2.save()保存配置 3.addScore()最高分排行榜,對數組賦值。* @author ZHF**/ public class Settings {//記錄聲音開起與關閉public static boolean soundEnabled = true;//默認分數排行榜分數public final static int[] highscores = new int[] {100, 80, 50, 30, 10};//保存的文件名public final static String file = ".superjumper";/**加載配置文件**/public static void load () {BufferedReader in = null;try {in = new BufferedReader(new InputStreamReader(Gdx.files.external(file).read()));soundEnabled = Boolean.parseBoolean(in.readLine());for (int i = 0; i < 5; i++) {highscores[i] = Integer.parseInt(in.readLine());}} catch (Exception e) {e.printStackTrace();} finally {try {if (in != null) in.close();} catch (IOException e) {}}}/**保存分值**/public static void save () {BufferedWriter out = null;try {//聲音的開關out = new BufferedWriter(new OutputStreamWriter(Gdx.files.external(file).write(false)));out.write(Boolean.toString(soundEnabled));for (int i = 0; i < 5; i++) {//將分數寫入文件out.write(Integer.toString(highscores[i]));}} catch (Exception e) {e.printStackTrace();} finally {try {if (out != null) out.close();} catch (IOException e) {}}}/**將所得分數與排行榜分數比較,從高到低重新排一下**/public static void addScore (int score) {for (int i = 0; i < 5; i++) {if (highscores[i] < score) {for (int j = 4; j > i; j--)highscores[j] = highscores[j - 1];highscores[i] = score;break;}}} }


? ?再次運行代碼,加了幾個金幣,分值發生變化了,回到主界面分數排行榜也發生變化了!(原先默認:100, 80, 50, 30, 10)


接下來就是聲音部分:


我們再次回到GameScreen中:

//實例化場景worldListener = new WorldListener() {@Overridepublic void jump () {Assets.playSound(Assets.jumpSound);}@Overridepublic void highJump () {Assets.playSound(Assets.highJumpSound);}@Overridepublic void hit () {Assets.playSound(Assets.hitSound);}@Overridepublic void coin () {Assets.playSound(Assets.coinSound);}};

? ?

? ?在監聽器中給對應方法播放對應的聲音,當然少不了在Asset中添加對聲音資源的加載:

聲明:

//聲音部分public static Sound clickSound; //按下音效public static Music music; //背景音樂public static Sound jumpSound; //跳躍public static Sound highJumpSound; //高跳public static Sound hitSound; //碰撞public static Sound coinSound; //金幣

實例化:

//背景音樂music = Gdx.audio.newMusic(Gdx.files.internal("data/music.mp3"));music.setLooping(true); //循環music.setVolume(0.5f); //大小if (Settings.soundEnabled) music.play();jumpSound = Gdx.audio.newSound(Gdx.files.internal("data/jump.ogg"));highJumpSound = Gdx.audio.newSound(Gdx.files.internal("data/highjump.ogg"));hitSound = Gdx.audio.newSound(Gdx.files.internal("data/hit.ogg"));coinSound = Gdx.audio.newSound(Gdx.files.internal("data/coin.ogg"));//點擊音效clickSound = Gdx.audio.newSound(Gdx.files.internal("data/click.ogg"));


ok!運行一下!貌似沒有什么問題,對應的聲音都播放出來了!


? 到此為止,libgdx中demo程序superjumper分版本的學習就結束了,由于本人也是邊學邊總結,中間肯定有許多地方講解的不完善,不妥的地方,這里先想大家說聲抱歉哈,希望大家發現問題能及時提出來,這樣我也能進步么!這里還是那句話,在學習新東西的時候,我們的不求甚解也不失為一種快速掌握的好方法! 希望這一些列學習筆記能幫助到初學者!


完整代碼下載:http://down.51cto.com/data/897232 ?代碼里詳細注解哦!


轉載于:https://blog.51cto.com/smallwoniu/1263957

總結

以上是生活随笔為你收集整理的libgdx游戏引擎开发笔记(十三)SuperJumper游戏例子的讲解(篇七)----各个物体的创建及其碰撞检测...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。