欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
2D WebGL renderer Pixi.js v4 入門(mén)【最終回】


上回學(xué)習了WebGL的各種圖像與文字的繪制。

檢測碰撞

上圖為理想狀態(tài)。

左邊的貓能夠使用鍵盤(pán)操作,右邊的塊是無(wú)法移動(dòng)的,然后上面的信息提示狀態(tài)。

在基于<第三回>的鍵盤(pán)控制所寫(xiě)的代碼中,

改造和追加了一部分代碼。

  1. var 貓, 塊, 消息, 狀態(tài);

  2. function setup(){

  3. 放入貓;

  4. 制作塊;

  5. 消息初始化;

  6. 設置鍵盤(pán)事件的移動(dòng)數值;

  7. 將狀態(tài)設定為play;

  8. gameLoop();

  9. }

  10. function play(){

  11. 接收鍵盤(pán)的移動(dòng)數值;

  12. if(碰撞){

  13. 變化塊的顏色和消息;

  14. }else{

  15. 回滾塊的顏色和消息;

  16. }

  17. }

  18. function 碰撞(r1, r2){

  19. 查找每個(gè)元素的中心點(diǎn);

  20. 計算每個(gè)元素一半的高和一半的寬;

  21. r1的一半高度和r2的一半高度相加;

  22. r1的一半寬度和r2的一半寬度相加;

  23. if(r1,r2的中心點(diǎn)距離 < r1,r2 相加的距離){

  24. 碰撞;

  25. }

  26. }

翻譯成代碼就是這樣

  1. var cat, box, message, state;

  2. function setup() {

  3. box = new PIXI.Graphics();

  4. box.beginFill(0xCCFF99);

  5. box.drawRect(0, 0, 64, 64);

  6. box.endFill();

  7. box.x = 120;

  8. box.y = 96;

  9. stage.addChild(box);

  10. cat = new Sprite(resources["images/cat.png"].texture);

  11. cat.x = 16;

  12. cat.y = 96;

  13. cat.vx = 0;

  14. cat.vy = 0;

  15. stage.addChild(cat);

  16. var left = keyboard(37),

  17. up = keyboard(38),

  18. right = keyboard(39),

  19. down = keyboard(40);

  20. left.press = function() {

  21. cat.vx = -5;

  22. cat.vy = 0;

  23. };

  24. left.release = function() {

  25. if (!right.isDown && cat.vy === 0) {

  26. cat.vx = 0;

  27. }

  28. };

  29. up.press = function() {

  30. cat.vy = -5;

  31. cat.vx = 0;

  32. };

  33. up.release = function() {

  34. if (!down.isDown && cat.vx === 0) {

  35. cat.vy = 0;

  36. }

  37. };

  38. right.press = function() {

  39. cat.vx = 5;

  40. cat.vy = 0;

  41. };

  42. right.release = function() {

  43. if (!left.isDown && cat.vy === 0) {

  44. cat.vx = 0;

  45. }

  46. };

  47. down.press = function() {

  48. cat.vy = 5;

  49. cat.vx = 0;

  50. };

  51. down.release = function() {

  52. if (!up.isDown && cat.vx === 0) {

  53. cat.vy = 0;

  54. }

  55. };

  56. message = new PIXI.Text(

  57. "No collision...",

  58. {font: "18px sans-serif", fill: "white"}

  59. );

  60. message.position.set(8, 8);

  61. stage.addChild(message);

  62. state = play;

  63. gameLoop();

  64. }

  65. function play() {

  66. cat.x += cat.vx;

  67. cat.y += cat.vy;

  68. if (hitTestRectangle(cat, box)) {

  69. message.text = "hit!";

  70. box.tint = 0xff3300;

  71. } else {

  72. message.text = "No collision...";

  73. box.tint = 0xccff99;

  74. }

  75. }

  76. function hitTestRectangle(r1, r2) {

  77. var hit, combinedHalfWidths, combinedHalfHeights, vx, vy;

  78. hit = false;

  79. r1.centerX = r1.x + r1.width / 2;

  80. r1.centerY = r1.y + r1.height / 2;

  81. r2.centerX = r2.x + r2.width / 2;

  82. r2.centerY = r2.y + r2.height / 2;

  83. r1.halfWidth = r1.width / 2;

  84. r1.halfHeight = r1.height / 2;

  85. r2.halfWidth = r2.width / 2;

  86. r2.halfHeight = r2.height / 2;

  87. vx = r1.centerX - r2.centerX;

  88. vy = r1.centerY - r2.centerY;

  89. combinedHalfWidths = r1.halfWidth + r2.halfWidth;

  90. combinedHalfHeights = r1.halfHeight + r2.halfHeight;

  91. if (Math.abs(vx) < combinedHalfWidths) {

  92. if (Math.abs(vy) < combinedHalfHeights) {

  93. hit = true;

  94. } else {

  95. hit = false;

  96. }

  97. } else {

  98. hit = false;

  99. }

  100. return hit;

  101. };

分析之后,發(fā)現還挺簡(jiǎn)單的。

如果沒(méi)問(wèn)題的話(huà)就進(jìn)入正題吧。

尋寶游戲

游戲原型大致是這樣:避開(kāi)怪物,獲取寶物,從門(mén)那里出去后成功。如果碰到怪物的話(huà)減少HP。減完了則判斷為輸。

代碼設計

  1. // pixi.js的初始化以及圖像的讀取

  2. function setup() {

  3. // 初始化,然后游戲狀態(tài)切換為play。

  4. // gameLoop();

  5. }

  6. function gameLoop() {

  7. // 描繪,并將精靈傳遞到render。

  8. }

  9. function play() {

  10. // 游戲所有的邏輯寫(xiě)這里。

  11. }

  12. function end() {

  13. // 游戲結束后。

  14. }

  15. // 其他必要的helper functions:

  16. // `keyboard`, `hitTestRectangle`, `contain` and `randomInt`

首先將游戲場(chǎng)景和游戲結束場(chǎng)景分開(kāi)。(不同的Container)

  1. gameScene = new Container();

  2. stage.addChild(gameScene);

  3. gameOverScene = new Container();

  4. stage.addChild(gameOverScene);

然后,先將gameOverScene隱藏。

  1. gameOverScene.visible = false;

游戲場(chǎng)景

首先將簡(jiǎn)單的洞窟背景、門(mén)、勇者、寶箱描繪出來(lái)。

  1. id = resources["images/treasureHunter.json"].textures;

  2. //洞窟

  3. dungeon = new Sprite(id["dungeon.png"]);

  4. gameScene.addChild(dungeon);

  5. //門(mén)

  6. door = new Sprite(id["door.png"]);

  7. door.position.set(32, 0);

  8. gameScene.addChild(door);

  9. //勇者

  10. explorer = new Sprite(id["explorer.png"]);

  11. explorer.x = 68;

  12. explorer.y = gameScene.height / 2 - explorer.height / 2;

  13. explorer.vx = 0;

  14. explorer.vy = 0;

  15. gameScene.addChild(explorer);

  16. //寶箱

  17. treasure = new Sprite(id["treasure.png"]);

  18. treasure.x = gameScene.width - treasure.width - 48;

  19. treasure.y = gameScene.height / 2 - treasure.height / 2;

  20. gameScene.addChild(treasure);

接下來(lái)制作隨機移動(dòng)的怪物。

  1. // 設定怪物數量

  2. var numberOfBlobs = 6,

  3. // 怪物與怪物之間的間距

  4. spacing = 48,

  5. // 從左邊開(kāi)始最初的空隙

  6. xOffset = 150,

  7. // 速度

  8. speed = 2,

  9. // 方向

  10. direction = 1;

  11. // 儲存怪物的數組

  12. blobs = [];

  13. // 按照設定的數值描繪怪物

  14. for (var i = 0; i < numberOfBlobs; i++) {

  15. // 怪物出生(?)

  16. var blob = new Sprite(id["blob.png"]);

  17. // 空出沿x軸一定距離的空間

  18. var x = spacing * i + xOffset;

  19. // y坐標(隨機)

  20. var y = randomInt(0, stage.height - blob.height);

  21. // 給與坐標

  22. blob.x = x;

  23. blob.y = y;

  24. // 方向(direction)為1的話(huà)向下,-1的話(huà)向上

  25. // 方向 乘以 速度

  26. blob.vy = speed * direction;

  27. // 下一只怪物為反方向

  28. direction *= -1;

  29. // 配置到數組中

  30. blobs.push(blob);

  31. gameScene.addChild(blob);

  32. }

然后是血條

  1. healthBar = new PIXI.DisplayObjectContainer();

  2. healthBar.position.set(stage.width - 170, 6)

  3. gameScene.addChild(healthBar);

  4. // HP血條的空間

  5. var innerBar = new PIXI.Graphics();

  6. innerBar.beginFill(0x000000);

  7. innerBar.drawRect(0, 0, 128, 8);

  8. innerBar.endFill();

  9. healthBar.addChild(innerBar);

  10. // HP血條的HP值

  11. var outerBar = new PIXI.Graphics();

  12. outerBar.beginFill(0xFF3300);

  13. outerBar.drawRect(0, 0, 128, 8);

  14. outerBar.endFill();

  15. healthBar.addChild(outerBar);

  16. healthBar.outer = outerBar;

這里出現的DisplayObjectContainer和Container和ParticleContainer的差異非常明顯呢。

另外,outer的意義現在還不是很清楚,等知道了補充。

游戲結束場(chǎng)景

準備好游戲結束后的生理和失敗的消息。

  1. // 寫(xiě)在之前隱藏gameOverScene代碼的后面

  2. message = new Text(

  3. "The End!",

  4. {font: "64px Futura", fill: "white"}

  5. );

  6. message.x = 120;

  7. message.y = stage.height / 2 - 32;

  8. gameOverScene.addChild(message);

play function

已經(jīng)準備好登場(chǎng)人物和怪物了,現在將游戲時(shí)要做什么列了一張表。

勇者移動(dòng),移動(dòng)范圍限制。
怪物的移動(dòng),移動(dòng)范圍限制,碰撞到墻壁時(shí)的反饋。
勇者和怪物碰撞了嗎?
勇者和寶箱碰撞了嗎?(獲得寶物)
勇者和門(mén)碰撞了嗎?(成功逃出)
游戲成功與失敗的判定

然后,整理一下吧!

作為helper function集中起來(lái)由play function調用比較好的有

范圍限制(判斷是否在邊界)
碰撞判斷

那么,改變代碼吧

  1. // 范圍限制(判斷是否在邊界)

  2. // 這里放入的值是能夠移動(dòng)、移動(dòng)中的精靈(這里為勇者和怪物)和可移動(dòng)范圍

  3. function contain(sprite, container) {

  4. var collision = undefined;

  5. // 左

  6. if (sprite.x < container.x) {

  7. sprite.x = container.x;

  8. collision = "left";

  9. }

  10. // 上

  11. if (sprite.y < container.y) {

  12. sprite.y = container.y;

  13. collision = "top";

  14. }

  15. // 右

  16. if (sprite.x + sprite.width > container.width) {

  17. sprite.x = container.width - sprite.width;

  18. collision = "right";

  19. }

  20. // 下

  21. if (sprite.y + sprite.height > container.height) {

  22. sprite.y = container.height - sprite.height;

  23. collision = "bottom";

  24. }

  25. // 返回值

  26. return collision;

  27. }

  1. // 判斷是否碰撞的函數

  2. function hitTestRectangle(r1, r2) {

  3. var hit, combinedHalfWidths, combinedHalfHeights, vx, vy;

  4. hit = false;

  5. r1.centerX = r1.x + r1.width / 2;

  6. r1.centerY = r1.y + r1.height / 2;

  7. r2.centerX = r2.x + r2.width / 2;

  8. r2.centerY = r2.y + r2.height / 2;

  9. r1.halfWidth = r1.width / 2;

  10. r1.halfHeight = r1.height / 2;

  11. r2.halfWidth = r2.width / 2;

  12. r2.halfHeight = r2.height / 2;

  13. vx = r1.centerX - r2.centerX;

  14. vy = r1.centerY - r2.centerY;

  15. combinedHalfWidths = r1.halfWidth + r2.halfWidth;

  16. combinedHalfHeights = r1.halfHeight + r2.halfHeight;

  17. if (Math.abs(vx) < combinedHalfWidths) {

  18. if (Math.abs(vy) < combinedHalfHeights) {

  19. hit = true;

  20. } else {

  21. hit = false;

  22. }

  23. } else {

  24. hit = false;

  25. }

  26. return hit;

  27. };

  1. // 雖然感覺(jué)沒(méi)必要獨立出來(lái),但還是和教程一樣分開(kāi)寫(xiě)吧

  2. function randomInt(min, max) {

  3. return Math.floor(Math.random() * (max - min + 1)) + min;

  4. }

放入play function

  1. function play() {

  2. // 用鍵盤(pán)事件中獲取的數值來(lái)移動(dòng)

  3. explorer.x += explorer.vx;

  4. explorer.y += explorer.vy;

  5. // 勇者的移動(dòng)范圍

  6. contain(explorer, {x: 28, y: 10, width: 488, height: 480});

  7. //contain(explorer, stage);

  8. // 給勇者一個(gè)沒(méi)有碰撞的初始設定

  9. var explorerHit = false;

  10. // 使用怪物的分布

  11. blobs.forEach(function(blob) {

  12. // 使其移動(dòng)

  13. blob.y += blob.vy;

  14. // 給怪物一個(gè)移動(dòng)范圍的限制,捕捉返回的值

  15. var blobHitsWall = contain(blob, {x: 28, y: 10, width: 488, height: 480});

  16. // 判斷返回的值,將方向反向

  17. if (blobHitsWall === "top" || blobHitsWall === "bottom") {

  18. blob.vy *= -1;

  19. }

  20. // 如果和勇者碰上了,就改變剛才碰撞的值

  21. if(hitTestRectangle(explorer, blob)) {

  22. explorerHit = true;

  23. }

  24. });

  25. // 如果勇者和怪物碰上了

  26. if(explorerHit) {

  27. // 一瞬間半透明

  28. explorer.alpha = 0.5;

  29. // HP削減

  30. healthBar.outer.width -= 1;

  31. } else {

  32. // 從半透明恢復

  33. explorer.alpha = 1;

  34. }

  35. // 如果勇者和寶箱碰撞

  36. if (hitTestRectangle(explorer, treasure)) {

  37. // 做一個(gè)手持寶箱的樣子(寶箱的位置一直跟隨在勇者右下角)

  38. treasure.x = explorer.x + 8;

  39. treasure.y = explorer.y + 8;

  40. }

  41. // HP歸零則游戲結束,彈出失敗信息

  42. if (healthBar.outer.width < 0) {

  43. state = end;

  44. message.text = "You lost!";

  45. }

  46. // 寶箱(和勇者)和門(mén)碰撞,游戲結束,彈出成功信息

  47. if (hitTestRectangle(treasure, door)) {

  48. state = end;

  49. message.text = "You won!";

  50. }

  51. }

然后用end function切換場(chǎng)景

  1. function end() {

  2. gameScene.visible = false;

  3. gameOverScene.visible = true;

  4. }

游戲完成

<點(diǎn)擊預覽游戲效果>

補充:關(guān)于精靈

精靈除了坐標、visible、旋轉之外還有各種設置,詳情可以在官方文檔中查找。

連接如下

Class: Sprite

基本上精靈是遵循繼承規則的

DisplayObject > Container > Sprite

就此教程結束。

各位看官辛苦了。

本回的代碼:進(jìn)入git

本文翻譯自:2D WebGL renderer Pixi.js v4【連載第六回】、2D WebGL renderer Pixi.js v4【連載最終回】
翻譯者:廣樹(shù)

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
AS3 跟隨鼠標的緩動(dòng)
Canvas2D mobile web game development – implementation | Tizen Developers
180行JavaScript代碼實(shí)現的小球隨機移動(dòng)代碼
高級動(dòng)畫(huà)
Flash基礎理論課 第八章 緩動(dòng)與彈性運動(dòng)Ⅰ
Matlab實(shí)現求兩點(diǎn)間的最短路徑
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久