2017-01-12 151 views
1

我只是想讓libgdx在我觸摸屏幕的任何位置創建圖片。libgdx在觸摸位置繪製圖像

這裏就是我有沒有做任何事情

SpriteBatch batch; 
Texture img; 

@Override 
public void create() { 
    batch = new SpriteBatch(); 
    img = new Texture("badlogic.jpg"); 
} 

@Override 
public void render() { 
    Gdx.gl.glClearColor(1, 0, 0, 1); 
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); 
} 

public class MyInputProcessor implements InputProcessor { 
    public boolean touchDown (int x, int y, int pointer, int button) { 
     batch.begin(); 
     batch.draw(img,Gdx.input.getX(),Gdx.input.getY()); 
     batch.end(); 
     return true; 
    } 
    ... (the rest of the input methods) 

,如果你不能告訴,我真的不知道我在做什麼呢,我認爲它與batch.draw()做在touchDown方法,而不是渲染區域,但我不知道從研究如何做到這一點不同的方式要麼

或者這也可能是所有錯了,點是我這樣做,這樣有希望學習正確的答案將幫助我瞭解一些關於java的一些重要事情

回答

1

LibGDX與基本上所有遊戲引擎一樣,每調用一次render()就會重新渲染整個場景。 render()以遊戲的幀頻重複調用(如果您沒有複雜且未優化的遊戲,則通常爲60fps)。您在render()方法中通常會執行的第一個與繪圖有關的操作是清除屏幕,您已使用Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);完成該屏幕。然後,重新繪製整個場景,以及自上一幀以來可能發生的任何變化。

您正在嘗試繪製render方法外的批處理內容。在這種情況下,你在觸碰時會這樣做。但是,由於只有在觸摸時才這樣做,對象將在下一次撥打render()時出現並消失,因此它只會在屏幕上顯示1/60秒。如果你想用一個輸入處理器來完成這個工作,你需要設置一些變量爲true來表示渲染方法應該繪製它,以及其他變量來表明它在哪裏繪製它。然後在render()方法中,如果變量爲真,則繪製東西。

其次,xy該輸入處理器獲取不一定(通常沒有)對應與在OpenGL中xy。這是因爲OpenGL具有自己的座標系,其座標系不一定與屏幕座標系完全相同。屏幕左上角有(0,0),Y軸向下,屏幕的寬度和高度與屏幕上實際像素的數量相匹配。 OpenGL在屏幕的中心有(0,0),Y軸向上,屏幕的寬度和高度都是2,而不管實際的屏幕像素如何。

但是OpenGL座標系是用投影矩陣修改的。 LibGDX相機類使這更簡單。對於2D繪圖,你需要一個OrthographicCamera。您可以使用相機設置OpenGL世界的寬度和大小,也可以定位相機。然後,將相機的計算矩陣傳遞給SpriteBatch,以便將場景定位在OpenGL空間中。

因此,要獲取輸入座標到場景的座標中,需要使用該攝像頭轉換座標。

最後,LibGDX不能奇蹟般地知道它應該將輸入命令傳遞給您創建的任何舊輸入處理器。您必須通過調用Gdx.input.setInputProcessor()來告訴它應該使用哪個InputProcessor。

因此,要解決你的類:

SpriteBatch batch; 
Texture img; 
boolean isTouchDown; 
final Vector3 touchPosition = new Vector3(); 
OrthographicCamera camera; 

@Override 
public void create() { 
    batch = new SpriteBatch(); 
    img = new Texture("badlogic.jpg"); 
    camera = new OrthographicCamera(); 
    Gdx.input.setInputProcessor(new MyInputProcessor()); // Tell LibGDX what to pass input to 
} 

@Override 
void resize (int width, int height) { 
    // Set the camera's size in relation to screen or window size 
    // In a real game you would do something more sophisticated or 
    // use a Viewport class to manage the camera's size to make your 
    // game resolution-independent. 
    camera.viewportWidth = width; 
    camera.viewportHeight = height; 

    camera.update(); // re-calculate the camera's matrices 
} 

@Override 
public void render() { 
    Gdx.gl.glClearColor(1, 0, 0, 1); 
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); 

    batch.setProjectionMatrix(camera.combined); // pass camera's matrices to batch 
    batch.begin(); 

    if (isTouchDown) { // Only draw this while the screen is touched. 
     batch.draw(img, touchPosition.x, touchPosition.y); 
    } 

    batch.end(); 
} 

public class MyInputProcessor implements InputProcessor { 
    public boolean touchDown (int x, int y, int pointer, int button) { 
     isTouchDown = true; 

     touchPosition.set(x, y, 0); // Put screen touch coordinates into vector 
     camera.unproject(touchPosition); // Convert the screen coordinates to world coordinates 
     return true; 
    } 

    public boolean touchUp (int screenX, int screenY, int pointer, int button){ 
     isTouchDown = false; 
     return true; 
    } 

    //... (the rest of the input methods) 
}