萬(wàn)網(wǎng)的怎么做網(wǎng)站地圖搜索網(wǎng)站排名
Java也可用于開(kāi)發(fā)一些動(dòng)畫(huà)。所謂動(dòng)畫(huà),就是間隔一定的時(shí)間(通常小于0 . 1秒 )重新繪制新的圖像,兩次繪制的圖像之間差異較小,肉眼看起來(lái)就成了所謂的動(dòng)畫(huà) 。
? 為了實(shí)現(xiàn)間隔一定的時(shí)間就重新調(diào)用組件的 repaint()方法,可以借助于 Swing 提供的Timer類(lèi),Timer類(lèi)是一個(gè)定時(shí)器, 它有如下一個(gè)構(gòu)造器 :
Timer(int delay, ActionListener listener): 每間隔 delay 毫秒,系統(tǒng)自動(dòng)觸發(fā) ActionListener 監(jiān)聽(tīng)器里的事件處理器方法,在方法內(nèi)部我們就可以調(diào)用組件的repaint方法,完成組件重繪。
案例2:
? 使用AWT畫(huà)圖技術(shù)及Timer定時(shí)器,完成下圖中彈球小游戲。
使用鍵盤(pán)左右鍵來(lái)控制粉色球拍的水平移動(dòng),小球碰到窗口邊界和球拍會(huì)反彈,并且落到球拍下方就會(huì)游戲結(jié)束并出現(xiàn)結(jié)束界面。
package Draw;import java.awt.*;
import java.awt.event.*;
import javax.swing.*;public class PinBall {//創(chuàng)建窗口對(duì)象private Frame frame = new Frame("彈球游戲");//1.設(shè)置桌面和球拍各自的寬度和高度private final int TABLE_WIDTH = 300;private final int TABLE_HEIGHT = 400;private final int RACKET_WIDTH = 60;private final int RACKET_HEIGHT = 20;//2.設(shè)置小球的大小,即小球的直徑private final int BALL_SIZE = 16;//3.記錄小球的坐標(biāo)//注意坐標(biāo)原點(diǎn)是窗口左上角private int ballX = 120; //并且初始化小球的坐標(biāo)private int ballY = 20;//4.設(shè)置小球在X和Y方向上分別移動(dòng)的速度private int speedY = 10;private int speedX = 5;//5.記錄球拍的坐標(biāo)private int racketX = 120;private final int racketY = 340; //球拍的Y坐標(biāo)一直不變,即球拍一直在水平移動(dòng)//6.游戲是否結(jié)束的標(biāo)識(shí)private boolean isOver = false;//7.定時(shí)器:聲明一個(gè)定時(shí)器private Timer timer;//8.畫(huà)布:自定義一個(gè)類(lèi),繼承Canvas,充當(dāng)畫(huà)布//只實(shí)現(xiàn)畫(huà)面的繪制,不管游戲邏輯的變換private class MyCanvas extends Canvas {@Overridepublic void paint(Graphics g) {//TODO 在這里繪制內(nèi)容if(isOver){//游戲結(jié)束g.setColor(Color.BLUE); //設(shè)置字體顏色g.setFont(new Font("Times", Font.BOLD,30)); //設(shè)置字體樣式g.drawString("游戲結(jié)束!",50,200); //設(shè)置內(nèi)容和位置(位置大概居中)}else {//游戲中//繪制小球g.setColor(Color.RED); //設(shè)置小球的顏色g.fillOval(ballX,ballY,BALL_SIZE,BALL_SIZE); //設(shè)置小球的坐標(biāo)和大小//繪制球拍g.setColor(Color.pink); //設(shè)置球拍的顏色g.fillRect(racketX,racketY,RACKET_WIDTH,RACKET_HEIGHT); //設(shè)置球拍的坐標(biāo)和大小}}}//9.畫(huà)筆:創(chuàng)建繪畫(huà)區(qū)域MyCanvas drawArea = new MyCanvas();public void init() {//組裝視圖,游戲邏輯的控制//如何控制小球和球拍的變換//10.完成球拍坐標(biāo)的變化,通過(guò)鍵盤(pán)左右鍵來(lái)實(shí)現(xiàn)KeyListener listener = new KeyAdapter() {@Overridepublic void keyPressed(KeyEvent e) {//獲取當(dāng)前按下的鍵int keyCode = e.getKeyCode();if(keyCode == KeyEvent.VK_LEFT) { //這個(gè)KeyEvent.VK_LEFT意味這是鍵盤(pán)的左箭頭//向左移動(dòng)//TODOif(racketX <= 10) racketX = 0;else racketX -= 10;}if(keyCode == KeyEvent.VK_RIGHT) {//向右移動(dòng)if(racketX > (TABLE_WIDTH - RACKET_WIDTH - 10)) racketX = TABLE_WIDTH - RACKET_WIDTH;else racketX += 10;}}};//給Frame和drawArea注冊(cè)監(jiān)聽(tīng)器frame.addKeyListener(listener);drawArea.addKeyListener(listener);//11.小球坐標(biāo)的控制ActionListener task = new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {//更新小球的坐標(biāo),重繪界面//根據(jù)邊界范圍,修正小球的速度 ,即碰到邊界會(huì)反彈if(ballX <= 0 || ballX >= (TABLE_WIDTH-BALL_SIZE)) {//碰到左邊界和右邊界speedX = -speedX;}if(ballY <= 0 || (ballY>racketY-BALL_SIZE && ballX>=racketX && ballX <racketX+RACKET_WIDTH)) {//碰到上邊界,以及碰到球拍,判定條件是小球y>球拍y,并且小球在球拍寬度的范圍內(nèi)speedY = -speedY;}if(ballY>racketY-BALL_SIZE && (ballX < racketX || ballX >racketX+RACKET_WIDTH)){//當(dāng)前小球超出了球拍能接到的范圍,游戲結(jié)束//停止定時(shí)器timer.stop();//修改游戲結(jié)束的標(biāo)記isOver = true;//重繪界面drawArea.repaint();}ballX += speedX;ballY += speedY;//重繪界面drawArea.repaint();}};timer = new Timer(100,task); //一百毫秒執(zhí)行一次timer.start();//組裝界面drawArea.setPreferredSize(new Dimension(TABLE_WIDTH,TABLE_HEIGHT));frame.add(drawArea);//設(shè)置frame最佳大小和可見(jiàn)性frame.pack();frame.setVisible(true);}public static void main(String[] args) {new PinBall().init();}
}