2015-10-14 82 views
0

我已經創建了一個簡單的AS3蛙類遊戲,並使用.hitTestObject來測試青蛙是否碰到任何障礙物。當青蛙碰到根本沒有接觸它的物體時,這是無效的。我是AS3的新手,不知道從哪裏開始編碼。任何幫助,將不勝感激!AS3青蛙像素完美碰撞

包{

import flash.display.*; 
import flash.events.*; 
import flash.utils.*; 
import flash.ui.*; 
import flash.events.Event; 
import flash.utils.Timer; 
import flash.events.TimerEvent; 
import flash.media.Sound; 
import flash.media.SoundChannel; 
import flash.utils.Timer; 
import flash.display.BitmapData; 
import flash.display.Bitmap; 

    public class Main extends MovieClip 
    { 
     //set variables 
     public var frog_spriteInstance:frog_sprite; 
     public var safeZoneInstance1 : safeZone; 
     public var safeZoneInstance2: safeZone; 
     public var safeZoneInstance3 : safeZone; 
     public var whitecar : car1; 
     public var whitecar1 : car1; 
     public var whitecar2 : car1; 
     public var truck1 : truck_sprite; 
     public var truck2: truck_sprite; 
     public var redcar : car_sprite; 
     public var redcar2 : car_sprite; 
     public var redcar3 : car_sprite; 
     public var log1 : log_sprite; 
     public var log2 : log_sprite; 
     public var log3 : log_sprite; 
     public var letters : Letters; 
     public var letters2 : Letters_2; 
     public var letters3 : Letters_3; 
     public var letters4 : Letters_4; 
     public var health : HealthBar; 
     public var firstletter : firstLetter; 
     public var secondletter : secondLetter; 
     public var thirdletter : thirdLetter; 
     public var fourthletter : fourthLetter; 

     var mysound:Sound = new (mySound); 


     public function Main() 
     { 
      // constructor code 
      safeZoneInstance1 = new safeZone(); 
      stage.addChild(safeZoneInstance1); 
      safeZoneInstance1.x = 300; 
      safeZoneInstance1.y=545 

      safeZoneInstance2 = new safeZone(); 
      stage.addChild(safeZoneInstance2); 
      safeZoneInstance2.x = 300; 
      safeZoneInstance2.y=300 

      safeZoneInstance3 = new safeZone(); 
      stage.addChild(safeZoneInstance3); 
      safeZoneInstance3.x = 300; 
      safeZoneInstance3.y=100 

      whitecar = new car1(); 
      stage.addChild(whitecar); 
      whitecar.x = 300; 
      whitecar.y = 500 

      whitecar1 = new car1(); 
      stage.addChild(whitecar1); 
      whitecar1.x = 550; 
      whitecar1.y = 480 

      whitecar2 = new car1(); 
      stage.addChild(whitecar2); 
      whitecar2.x = 50; 
      whitecar2.y = 480 

      truck1 = new truck_sprite(); 
      stage.addChild (truck1); 
      truck1.x = 1000; 
      truck1.y = 430 

      truck2 = new truck_sprite(); 
      stage.addChild (truck2); 
      truck2.x = 300; 
      truck2.y = 430 

      redcar = new car_sprite(); 
      stage.addChild (redcar); 
      redcar.x = 300; 
      redcar.y = 340 

      redcar2 = new car_sprite(); 
      stage.addChild (redcar2); 
      redcar2.x = 100; 
      redcar2.y = 375 

      redcar3 = new car_sprite(); 
      stage.addChild (redcar3); 
      redcar3.x = 500; 
      redcar3.y = 375 

      log1 = new log_sprite(); 
      stage.addChild(log1); 
      log1.x = 300; 
      log1.y = 230 

      log2 = new log_sprite(); 
      stage.addChild(log2); 
      log2.x = 100; 
      log2.y = 150 


      log3 = new log_sprite(); 
      stage.addChild(log3); 
      log3.x = 500; 
      log3.y = 150 

      letters = new Letters(); 
      letters.x = randomRange(100,500) ; 
      letters.y = randomRange(100,500); 
      stage.addChild(letters); 

      letters2 = new Letters_2(); 
      letters2.x = randomRange(100,500) ; 
      letters2.y = randomRange(100,500); 
      stage.addChild(letters2); 

      letters3 = new Letters_3(); 
      letters3.x = randomRange(100,500) ; 
      letters3.y = randomRange(100,500); 
      stage.addChild(letters3); 

      letters4 = new Letters_4(); 
      letters4.x = randomRange(100,500) ; 
      letters4.y = randomRange(100,500); 
      stage.addChild(letters4); 

      frog_spriteInstance = new frog_sprite(); 
      stage.addChild(frog_spriteInstance); 
      frog_spriteInstance.x=300; 
      frog_spriteInstance.y=550; 

      health = new HealthBar(); 
      stage.addChild(health); 
      health.x = 130; 
      health.y = 20; 
      health.width = 100; 

      stage.addEventListener(KeyboardEvent.KEY_DOWN, moveFrog); 

      stage.addEventListener(Event.ENTER_FRAME, movecars); 

      stage.addEventListener(Event.ENTER_FRAME, movetrucks); 

      stage.addEventListener(Event.ENTER_FRAME, moveredcars); 

      stage.addEventListener(Event.ENTER_FRAME, movelogs); 

      stage.addEventListener(Event.ENTER_FRAME,checkforcollision); 

      mysound.play(); 
     } 

     public function moveFrog(e:KeyboardEvent) 
     { 
      // get the key pressed and then move the player 

      { 
       if (e.keyCode == Keyboard.UP) 
       { 
        frog_spriteInstance.rotation = 0; 
        frog_spriteInstance.y -= 50; 
       } 
       if (e.keyCode == Keyboard.DOWN) 
       { 
        frog_spriteInstance.rotation = 180; 
        frog_spriteInstance.y += 50; 
       } 
       if (e.keyCode == Keyboard.LEFT) 
       { 
        frog_spriteInstance.rotation = -90; 
        frog_spriteInstance.x -= 50; 
       } 
       if (e.keyCode == Keyboard.RIGHT) 
       { 
        frog_spriteInstance.rotation = 90; 
        frog_spriteInstance.x += 50; 
       } 

      } 
     } 

     function movecars(event:Event) 
     { 
      //move cars across screen and when they disappear, reappear at the other side 
      whitecar.x -= 3; 

      if (whitecar.x<-100){ 
      whitecar.x=650; 
      } 
      whitecar1.x -= 3; 

      if (whitecar1.x<-100){ 
      whitecar1.x=650; 
      } 
      whitecar2.x -= 3; 

      if (whitecar2.x<-100){ 
      whitecar2.x=650; 
      } 
     } 

     function movelogs(event:Event) 
     { 
      //move logs across screen and when they disappear, reappear at the other side 
      log1.x -= 5; 

      if (log1.x<-100){ 
      log1.x=650; 
      } 
      log2.x -= 5; 

      if (log2.x<-100){ 
      log2.x=650; 
      } 
      log3.x -= 5; 

      if (log3.x<-100){ 
      log3.x=650; 
      } 
     } 

     function movetrucks(event:Event) 
     { 
      //move trucks across screen and when they disappear, reappear at the other side 
      truck1.x +=3; 

     if (truck1.x>650){ 
      truck1.x=-100; 
      } 
      truck2.x +=3; 

     if (truck2.x>650){ 
      truck2.x=-100; 
      } 

     } 

     function moveredcars(event:Event) 
     { 
      //move red cars across screen and when they disappear, reappear at the other side 
      redcar.x +=3; 

     if (redcar.x>650){ 
      redcar.x=-100; 
      } 
      redcar2.x +=3; 

     if (redcar2.x>650){ 
      redcar2.x=-100; 
      } 
      redcar3.x +=3; 

     if (redcar3.x>650){ 
      redcar3.x=-100; 
      } 
     } 

     function checkforcollision(event:Event) 
     { 
      //check for collisions 
      if (frog_spriteInstance.hitTestObject(log1) || (frog_spriteInstance.hitTestObject(log2) || (frog_spriteInstance.hitTestObject(log3) || (frog_spriteInstance.hitTestObject(whitecar) || (frog_spriteInstance.hitTestObject(whitecar1) || (frog_spriteInstance.hitTestObject(whitecar2) || (frog_spriteInstance.hitTestObject(log2) || (frog_spriteInstance.hitTestObject(truck1) || (frog_spriteInstance.hitTestObject(truck2) || (frog_spriteInstance.hitTestObject(redcar) || (frog_spriteInstance.hitTestObject(redcar2) || (frog_spriteInstance.hitTestObject(redcar3))))))))))))){ 
      //reset frog if hits an obstacle 
      stage.addChild(frog_spriteInstance); 
      frog_spriteInstance.x=300; 
      frog_spriteInstance.y=550; 
      //reduce health bar 
      health.width -= 10; 
      } 
      //remove event listeners when health is empty 
      if (health.width == 0){ 
      stage.removeEventListener(Event.ENTER_FRAME, movecars); 
      stage.removeEventListener(KeyboardEvent.KEY_DOWN, moveFrog); 
      stage.removeEventListener(Event.ENTER_FRAME, movetrucks); 
      stage.removeEventListener(Event.ENTER_FRAME, moveredcars); 
      stage.removeEventListener(Event.ENTER_FRAME, movelogs); 
      } 
      //add letters to bottom of screen when hit correctly 
      if (frog_spriteInstance.hitTestObject(letters)){ 
       stage.addChild(frog_spriteInstance); 
       frog_spriteInstance.x=300; 
       frog_spriteInstance.y=550; 
       stage.removeChild(letters); 
       firstletter = new firstLetter(); 
       stage.addChild(firstletter); 
       firstletter.x=345; 
       firstletter.y=600; 
      } 
      if (frog_spriteInstance.hitTestObject(letters2)){ 
       stage.addChild(frog_spriteInstance); 
       frog_spriteInstance.x=300; 
       frog_spriteInstance.y=550; 
       stage.removeChild(letters2); 
       secondletter = new secondLetter(); 
       stage.addChild(secondletter); 
       secondletter.x=206; 
       secondletter.y=600; 

      } 
      if (frog_spriteInstance.hitTestObject(letters3)){ 
       stage.addChild(frog_spriteInstance); 
       frog_spriteInstance.x=300; 
       frog_spriteInstance.y=550; 
       stage.removeChild(letters3); 
       thirdletter = new thirdLetter(); 
       stage.addChild(thirdletter); 
       thirdletter.x=273; 
       thirdletter.y=600; 

      } 
      if (frog_spriteInstance.hitTestObject(letters4)){ 
       stage.addChild(frog_spriteInstance); 
       frog_spriteInstance.x=300; 
       frog_spriteInstance.y=550; 
       stage.removeChild(letters4); 
       health.width -= 10; 
       fourthletter = new fourthLetter(); 
       stage.addChild(fourthletter); 
       fourthletter.x=25; 
       fourthletter.y=620; 
      } 
     } 

     function randomRange(minNum:Number, maxNum:Number):Number 
     { 
      //random generator for letter positioning 
      return (Math.floor(Math.random() * (maxNum - minNum + 1)) + minNum); 
     } 
    } 

}

而且我的代碼是非常狡猾等改進建議都非常歡迎。

回答

2

要從兩個任意顯示對象執行像素完美命中測試,您必須將它們繪製爲位圖並使用BitmapData/hitTest()

這裏是一個廣義函數,這是否:

function hitTestShapes(object1:DisplayObject, object2:DisplayObject, threshold:uint = 1):Boolean { 

    var bounds1:Rectangle = object1.getBounds(object1.parent); 
    var matrix1:Matrix = object1.transform.matrix; 
    matrix1.tx = object1.x - bounds1.x; 
    matrix1.ty = object1.y - bounds1.y; 
    var bmp1:BitmapData = new BitmapData(bounds1.width, bounds1.height, true, 0); 
    bmp1.draw(object1, matrix1); 

    var bounds2:Rectangle = object2.getBounds(object2.parent); 
    var matrix2:Matrix = object2.transform.matrix; 
    matrix2.tx = object2.x - bounds2.x; 
    matrix2.ty = object2.y - bounds2.y; 
    var bmp2:BitmapData = new BitmapData(bounds2.width, bounds2.height, true, 0); 
    bmp2.draw(object2, matrix2); 

    return bmp1.hitTest(bounds1.topLeft, threshold, bmp2, bounds2.topLeft, threshold); 
} 

注意,雖然,繪製成位圖是相當緩慢的,所以要小心不要過度使用這種功能,或者你將有性能問題。實際上,首先使用hitTestObject()是一個好主意,它非常快速並檢測邊界框交叉點,然後只調用hitTestShapes()來優化檢查。換句話說:

if (frog_spriteInstance.hitTestObject(log1) && hitTestShapes(frog_spriteInstance, log1)) { } 

至於您的代碼的建議,還有用於去複製一個很大的潛力通過陣列的方式,循環和功能。例如,而不是定義所有的對象作爲獨立變量,只是它們都存儲在一個陣列(或向量):

public var safeZones:Array = []; 
public var obstacles:Array = []; 
public var letters:Array = []; 

要填充的數組,你可以推到它們的值,並使用功能整合所有你重複的對象設置代碼:

(代碼約定注:使用「UpperCamelCase」類的名字。)

public function Main(){ 
    addSafeZone(300, 545); 
    addSafeZone(300, 300); 
    addSafeZone(300, 100); 

    addObstacle(WhiteCar, 300, 500); 
    addObstacle(WhiteCar, 550, 480); 
    addObstacle(WhiteCar, 50, 480); 

    addObstacle(Truck, 1000, 430); 
    addObstacle(Truck, 300, 430); 

    addObstacle(RedCar, 300, 340); 
    addObstacle(RedCar, 100, 375); 
    addObstacle(RedCar, 500, 375); 

    addObstacle(Log, 300, 230); 
    addObstacle(Log, 100, 150); 
    addObstacle(Log, 500, 150); 

    addRandomLetters(Letters_1); 
    addRandomLetters(Letters_2); 
    addRandomLetters(Letters_3); 
    addRandomLetters(Letters_4); 
} 

private function addSafeZone(x:Number, y:Number):void { 
    var safeZone:SafeZone = new SafeZone(); 
    stage.addChild(safeZone); 
    safeZone.x = x; 
    safeZone.y = y 
    safeZones.push(safeZone); 
} 

private function addObstacle(spriteClass:Class, x:Number, y:Number):void { 
    var obstacle:Sprite = new spriteClass(); 
    stage.addChild(obstacle); 
    obstacle.x = x; 
    obstacle.y = y 
    obstacles.push(obstacle); 
} 

private function addRandomLetters(lettersClass:Class):void { 
    var lettersSprite:Sprite = new lettersClass(); 
    lettersSprite.x = randomRange(100, 500); 
    lettersSprite.y = randomRange(100, 500); 
    stage.addChild(lettersSprite); 
    letters.push(lettersSprite); 
} 

現在你可以循環數組上進行所有的操作。例如,要檢查是否有碰到任何障礙:

for each(var obstacle:DisplayObject in obstacles){ 
    if(frog.hitTestObject(obstacle) && hitTestShapes(frog, obstacle)){ 
     // The frog hit an obstacle! 
    } 
} 

您還可以結合所有的「移動」功能基於其類型之一,其移動每個障礙:

private function moveObstacles(e:Event):void { 
    for each(var obstacle in obstacles){ 
     if(obstacle is WhiteCar){ 
      obstacle.x -= 3; 
     } 
     else if(obstacle is RedCar){ 
      obstacle.x += 3; 
     } 
     else if(obstacle is Truck){ 
      obstacle.x += 3; 
     } 
     else if(obstacle is Log){ 
      obstacle.x -= 5; 
     } 

     if(obstacle.x < -100){ 
      obstacle.x = 650; 
     } 
     else if(obstacle.x > 650){ 
      obstacle.x = -100; 
     } 

    } 
} 

最後,你真的應該只需要一個ENTER_FRAME處理程序。只需從那裏調用你想要的任何功能即可。添加多個ENTER_FRAME處理程序可能會麻煩管理。例如,只是這樣做:

addEventListener(Event.ENTER_FRAME, update); 

private function update(e:Event):void { 
    moveObstacles(); 
    doOtherStuff(); 
    anythingYouNeedToDo(); 
} 

這樣,你只需要removeEventListener(Event.ENTER_FRAME, update)停止比賽,而不是一大堆ENTER_FRAME處理程序。

我還沒有測試過任何這些代碼,但是你得到了一般的想法。如果您有任何問題,請告訴我,我可以提供幫助。

+0

非常感謝!代碼現在運行良好,但是當嘗試添加青蛙和鍵盤偵聽器以使其現在移動時,出現錯誤。讓它移動的最好方法是什麼? –