亂侃
我上完了一個學期的Java課程,想自己做一些Java小遊戲來玩玩,才發現一個學期在課堂上學習的東西簡直太少太少了。 即使期末考試拿到高分,但是實際應用起來,要做一個遊戲程式,發現並不是那麼容易……
本來想做一個超級瑪麗的遊戲,但是完全沒有頭緒……
後來去找CC老師指引人生方向,得知可以先試試做《推箱子》一類的遊戲,即如何控制物體移動;接下來可以試試做《貪食蛇》,即在沒有使用者輸入的時候物體仍然在自動移動;這兩個任務完成了之後,再考慮《超級瑪麗》的事情。
假設你和我一樣剛剛學會了Java基本概念,但處於一個難以應用的境界。第一篇《Java遊戲點滴》將介紹如何使用KeyListener來做一個簡單的控制物體移動。
本文
我們要達到的目的,是在JFrame裡畫一個圓形,通過方向鍵控制圓形移動。
首先,我們建立一個類,這個類繼承JFrame,我們的程式完全使用這一個類完成。接下來按照課堂上學的方法,覆蓋掉JFrame的預設建構函式,將JFrame進行初始化,不再細說了。
要畫一個圓形,很顯然需要幾個成員變數來記錄圓形的位置和半徑。
private int x,y;
private int r;
然後我們需要實現KeyListener介面,並且覆蓋這個介面的三個抽象方法:
public void keyPressed ( KeyEvent e ) {}
public void keyReleased ( KeyEvent e ) {}
public void keyTyped ( KeyEvent e ) {}
別忘了給JFrame註冊監聽器,即在JFrame的建構函式當中加入addKeyListener(this);這句。
當按下方向鍵的時候,我們改變x,y的座標值,使得圓形在面板上移動。(注意,我們這裡只是設定了圓形的幾個參數,並沒有將圓形繪製到螢幕上去。關於繪製我們放在後面)實現這個功能的代碼寫在keyPressed方法中,即按下鍵盤時執行這些語句。
這裡遇到一個很實際的問題:在keyPressed方法中如何得知按下的是那個鍵?
這個問題的答案就在keyPressed方法參數KeyEvent e當中,參數中就包含了所按下按鍵的資訊。使用e.getKeyCode()方法會返回一個int型的值。單純看這個值也一時不能判斷哪個按鍵。
幸運的是KeyEvent類中定義了所有的鍵盤按鍵常量,用e.getKeyCode()方法獲得的值與這些常量判等,就能知道按下的是什麼鍵。下面給出常用的按鈕的常量:
KeyEvent.VK_SPACE 空格
KeyEvent.VK_ENTER 斷行符號
KeyEvent.VK_SHIFT shift
KeyEvent.VK_CONTROL ctrl
KeyEvent.VK_A ~ Z A ~ Z
KeyEvent.VK_0 ~ 9 0 ~ 9
KeyEvent.VK_UP 方向鍵 上
KeyEvent.VK_DOWN 下
KeyEvent.VK_LEFT 左
KeyEvent.VK_RIGHT 右
這樣,我們的keyPressed方法可以這樣寫:
public void keyPressed(KeyEvent e){
int key = e.getKeyCode(); //擷取按鍵碼
switch(key){
case KeyEvent.VK_UP: //按下方向鍵 上
y-=10; break;
case KeyEvent.VK_DOWN: //按下方向鍵 下
y+=10; break;
case KeyEvent.VK_LEFT: //按下方向鍵 左
x-=10; break;
case KeyEvent.VK_RIGHT: //按下方向鍵 右
x+=10; break;
}
//在這裡繪製圖形
}
那麼,這個程式的核心我們算是完成了,後面的工作僅僅是將圓形按照當前的座標繪製到螢幕上。
要在JFrame中繪製圖形,需要用到JFrame的getGraphics()方法,它可以擷取這個組件的圖形上下文,它返回一個Graphics類的對象,這個對象可以向組件中繪製各種圖形圖片文字等。
Graphics類提供了繪製橢圓的方法,g.fillOval(x, y, w, h);它將繪製一個以x,y為左上方w,h為寬高的矩形作為外框的橢圓。繪製圓形只需把這個矩形設定成正方形。
在keyPressed()方法的最後加上這樣兩句話:
Graphics g = this.getGraphics();
g.fillOval(x-r, y-r, 2*r, r*2);
目前為止,程式基本完成。在main()方法中new你的這個類就可以運行了。當然不要忘了在建構函式中寫必要的設定和初始化x,y,r的值。
運行後你會發現一個問題,按下方向鍵雖然有一個圓形在移動,但是移動之前的圖象仍然殘留在螢幕上。其原因是使用Graphics類在組件中繪製圖形時每次繪製都是在上一次繪製的基礎上進行的,清除螢幕需要手動進行。
所以我們應該在畫圓形之前清除螢幕上的圖象:
g.clearRect(0, 0, 600, 400); //這裡後兩個參數是你設定JFrame的寬度和高度
這裡給出整個程式的代碼:
-----------------------------------------------------------------------------------------
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class MoveItem extends JFrame implements KeyListener{
private int x,y;
private int r;
//預設建構函式
public MoveItem(){
x=300;
y=200;
r=50;
this.setSize(600, 400);
this.addKeyListener(this);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
//KeyListener方法
public void keyReleased(KeyEvent e){}
public void keyTyped(KeyEvent e){}
public void keyPressed(KeyEvent e){
int key = e.getKeyCode(); //擷取按鍵碼
switch(key){
case KeyEvent.VK_UP: //向上
y-=10; break;
case KeyEvent.VK_DOWN: //向下
y+=10; break;
case KeyEvent.VK_LEFT: //向左
x-=10; break;
case KeyEvent.VK_RIGHT: //向右
x+=10; break;
}
//繪製圖形
Graphics g = this.getGraphics();
g.clearRect(0, 0, 600, 400);
g.fillOval(x-r, y-r, 2*r, r*2);
}
//main方法
public static void main(String args[]){
new MoveItem();
}
}
---------------------------------------------------------------------------------------
這個移動圓形的程式也就完成了。你會發現這個程式存在許多問題,而這些問題也就是我們以後需要解決的。粗略得列一下存在的問題:
1。初始時看不到圖象,只有按下按鍵只有才顯示出來。
2。你也許會發現圓形移動時,螢幕會出現嚴重的閃爍。
3。控制不夠平緩,手感不好。
4。圖形不能自動運動。
…… ……
小節
這個程式中,值得研究的東西一個是KeyEvent類,另一個是Graphics類。
事件監聽在程式中用得十分常見,應該熟悉如何對各種組件添加不同的事件監聽器。