HOME 回資訊服務處首頁 Login
ITs通訊
搜尋電子報


含詳全文
訂閱電子報
請輸入E-Mail
 
 
2017.01.05 2017年第1期 設為首頁 | 加入最愛 | RSS 訂閱
最新電子報 | 上一期 | 下一期 | 各期電子報


   
中央研究院資訊服務處通訊
中央研究院資訊服務處發行
2017年第1期   民國106年1月5日
資訊服務處進行全院資訊服務滿意度調查106/1/12截止

 嶄新的一年已經到來,資訊服務處感謝您在過去一年的支持與鼓勵。為了解大家對資訊服務處提供各項服務的看法,爰進行本次全院服務滿意度調查,希藉由您提供的寶貴意見,讓我們的各項服務能更完善、更美好。為了感謝您的意見回饋,我們將在調查結束後,抽出100名參與者致贈小禮物,獎品包含喇叭、生活小物、紀念品等。調查日期即日起至106/1/12止,歡迎踴躍參與!也非常謝謝您這一年對資訊服務處的支持!

 請所處同仁點選全院服務滿意度調查連結開始填寫問卷,謝謝您的參與。
 

Top

106年資訊處推廣課程公告

上課日期

課程名稱

建議對象

地點

2017/1/17(二)
2017/1/20(五)
14:00-17:00
ACCESS 表單查詢與報表設計 對資料表建立與資料表間的關聯已有概念者 人文館
遠距會議室
2017/01/23(一)
14:00-17:00
MAC系統操作入門 想要學習MAC作業系統者 人文館
遠距會議室
2017/02/15(三)
2017/02/21(二)
14:00-17:00
Word 長篇排版原理與操作 有接觸過基礎排版者 人文館
遠距會議室
2017/02/20(一)
2017/02/22(三)
14:00-17:00
Excel常用函數解析(一) 具備Excel基礎認知者 人文館
遠距會議室
2017/03/15(三)
14:00-17:00
Office範本製作與自動化設定 具備office基礎觀念者 人文館
遠距會議室
2017/04/12(三)
14:00-17:00
Adobe Acrobat 建立PDF相關功能 對 Acrobat Adobe DC 相關應用有興趣者,適合初階至初進階使用者的學習內容 人文館
遠距會議室
2017/04/26(三)
2017/05/03(三)
2017/05/10(三)
2017/05/17(三)
09:00-17:30
Python與大數據與物聯網的實作 需有簡單程式設計基礎,如C/Java、Python並具有高中代數基礎觀念者 人文館
遠距會議室
2017/04/28(五)
14:00-17:00
使用GanttProject進行專案與時程管理 希望將工作項目有效的進行時程管理之使用者 人文館
遠距會議室
2017/05/15(一)
2017/05/18(四)
14:00-17:00
Excel 2013 大數據資料統計與分析(二) 1 熟悉EXCEL 2013使用的同仁
2. 想進一步使用EXCEL 2013樞紐分析功能的同仁
3 想學習PowerPivot進行資料分析的同仁
人文館
遠距會議室
2017/06/06(二)
14:00-17:00
使用GIMP美編軟體進行文宣設計 有需要進行文宣美編設計者 人文館
遠距會議室
2017/06/27(二)
2017/06/30(五)
14:00-17:00
Excel巨集辦公室自動化(三) 孰悉Excel基礎操作之使用者 人文館
遠距會議室

推廣課程聯絡窗口:

中央研究院資訊處 資訊訓練與推廣服務
Email:train@sinica.edu.tw
TEL:02-2789-8863

Top

近期惡意信件整理
 惡意電子郵件主要利用網路使用者的好奇心及其他人性弱點,以聳動的標題、關鍵字或內容,誘使使用者開啟藏有惡意程式碼、附件,或是惡意外部連結的電子郵件;有時,該郵件並會結合新聞時事,或是假冒使用者所認識的往來對象來寄送郵件。使用者於開啟惡意電子郵件後,所使用的電腦設備將可能被植入後門或木馬程式,造成機敏資料外洩之風險。

 同仁除了應定期對所使用電腦之作業系統(如Windows)及應用軟體(如Office、Java等)進行修補程式之更新外,另於開啟電子郵件時,亦請特別留意含有以下所列主旨、內容及附件之郵件:

一、資訊服務處資安組彙整近期院內同仁收到之惡意信件主旨及附檔名供參考:

  • Returned mail: Data format error

  • Delivery reports about your e-mail

  • [!10199]: ALMA Helpdesk Triage - simulator

  • Boas Festas e Próspero Ano Novo

  • Re: Re: Quotation Request (22/12/16)

  • Outstanding payment

二、有關惡意信件判斷方式可參閱ITs通訊「近期惡意信件案例分析」一文。

Top

資安通報
 資安通報資訊,主要根據「國家資通安全會報技術服務中心」所發布的資安消息而來,舉凡病毒漏洞、弱點檢測、微軟資安等均為通報的主要內容,近期值得同仁關注的資安通報如下,請使用者留意,並儘速更新相關程式及軟體!
Top

一項資料庫開放使用

 以下資料庫開放使用,歡迎試用 :

Top

1/19~20日舉行「2017台北國際電玩展」

 邁入第15年的「台北國際電玩展Taipei Game Show」是全台唯一以「遊戲產業」為主,兼具B2B(專業展)與B2C(消費展)的綜合性展覽。這一次的展覽主題為「穿越遊戲時空In the Game, To the World.」,隨著虛擬實境技術的進步,人們可以真實地進入遊戲世界,在遊戲裡盡情穿梭在不同的世界、體驗前所未有的感動。

  • 活動時間:
    • B2B ZONE 商務區
      參觀對象:專業人士(B2B)
      基本資訊:2017年1月19日(四)至1月20日(五)台北世貿一館H區(2樓)
      入場方式:事先申請 (至2017/01/06截止)
    • B2C AREA 玩家區
      參觀對象:社會大眾(B2C)
      基本資訊:2017年1月20日(五)至1月24日(二)10:00~18:00台北世貿一館(1樓)
      入場方式:預購票或現場購票
  • 活動地點:世貿一館
  • 活動官網:http://tgs.tca.org.tw/index.php
Top

網頁2D遊戲開發-以打磚塊遊戲為例

 本文取材自MDN (Mozilla Developer Network)中的「2D breakout game using pure JavaScript」一文,為了避免篇幅過長,精簡了許多原文中的細節,可在閱讀完本文後再瀏覽原文一遍。在這份自學教學中,將一步一步的做出簡單的2D打磚塊遊戲。整個遊戲將在網頁中由純粹的JavaScript碼寫成,並使用HTML5的<canvas>畫布標籤,在此畫布上進行繪圖呈現。每一個步驟都有線上可編輯的程式碼可以實際操作,所以你可以看到一步一步進行中的中間階段呈現的樣子。你將學習使用<canvas>元素來實現基本遊戲機制(例如繪圖呈現和移動圖像,碰撞檢測,控制機制以及獲勝和失敗狀態)的基礎知識。為了充分學習,你應該已經具備基本的JavaScript知識。在完成本教學後,希望你能夠構建其他簡單的網頁遊戲,當然也可以將此知識運用在一般網頁上非遊戲類的圖形繪製。

 一開始入門時使用純粹的JavaScript碼就能夠學到紮實的網頁遊戲開發知識,之後你能自由選擇任何你喜歡的框架(Framework)、Library或是Game engine來完成你的專案。框架(Framework)是由JavaScrip碼寫成的工具,雖然你可能預期使用框架(framework)來開發遊戲,但先學習使用純粹的JavaScrip是個不錯的方式來瞭解被框架隱藏的細節。框架加速了開發時程和解決一些遊戲中無聊的部份,但有時候遊戲不如想像的方式運作時,你永遠可以試著除錯或撰寫純粹JavaScript碼的解決方案。

 本教學中包含了十個步驟,其所有的程式碼可以在GitHub找到。最後在第十個步驟所完成的遊戲畫面如下圖所示。你也可以直接在線上執行完成的遊戲,操作時可以使用鍵盤上的向左及向右鍵或是滑鼠控制下方球拍的移動,遊戲提供最多有三條生命可使用,遊戲的目標是消滅上方的磚塊。

  1. 建立Canvas並繪圖
    在開始撰寫遊戲功能之前,先使用HTML的<canvas>元素建構遊戲中負責呈現繪圖畫面的畫布。在HTML檔中撰寫如下的HTML碼,就可建立480x320的繪圖區:

    <canvas id="myCanvas" width="480" height="320"></canvas>

    在Canvas的繪圖區可以叫用繪圖函數來繪製圓形或長方形等圖形,例如在HTML檔中的<script>程式區中加入下列Javascript程式碼進行繪圖:

    var canvas = document.getElementById("myCanvas"); // 取用id=myCanvas的元素
    var ctx = canvas.getContext("2d"); // 2D畫布物件

    ctx.beginPath(); // 開始繪製
    ctx.rect(20, 40, 50, 50); // 繪製長方形,左上角座標為(20,40),寬=50,高=50
    ctx.fillStyle = "#FF0000"; // 填入紅色
    ctx.fill(); // 填滿長方形
    ctx.closePath();
    ctx.beginPath();
    ctx.arc(240, 160, 20, 0, Math.PI*2, false); // 繪製圓形,中心座標為(240, 160)
    ctx.fillStyle = "green"; // 填入綠色
    ctx.fill(); // 填滿圓形
    ctx.closePath();

    繪圖時由beginPath()開始繪製一個圖形路徑,直到closePath()為止。arc()是繪製一個圓形或是圓形的一部份,也就是圓弧形線段,所以參數中需要圓弧的起始角度以及結束角度,其中2倍結束角度Math.PI值就是360度的圓圈,再由fill()填滿就成為圓球了!

    請注意畫布的左上角座標為(0,0),X軸向右的方向為正值,Y軸向下的方向為正值,如下圖。

    此步驟的完整程式碼:GitHub
    線上測試程式碼:點此在JSFiddle上實際運行並測試或修改程式碼。

    JSFiddle是線上測試JavaScript、CSS及HTML碼的平台。你不用自己準備Web伺服器、在電腦開啟編輯程式及儲存檔案,就可以執行、修改及再執行程式碼了,是學習時的最佳工具。如下圖,進入平台後只要修改程式碼,再點選左上角的「Run」之後,就可以在右下角的視窗中看到執行結果了!

  2. 讓球動起來
    藉由在螢幕上繪製球,然後清除,接著在每個影格中偏移一點點的位置再繪製新的球,造成物體移動的錯覺,這就是電影中移動物體的原理。程式將會有個無窮盡的主迴圈定時產生影格、繪製球、改變球的位置及清除畫面等功能所組成。程式中(x,y)為球中心的座標、dx,dy為球在x軸及y軸的偏移量、函數draw()繪製影格畫面中的圖形及球,並使用JavaScript的定時函數setInterval(draw, 10),以每10msec的速度,無止盡的呼叫函數draw(),且在影格繪製前清除畫面。程式的主要片段如下:

    var x = canvas.width/2;
    var y = canvas.height-30;
    var dx = 2;
    var dy = -2;

    function drawBall() {
        ctx.beginPath();
        ctx.arc(x, y, 10, 0, Math.PI*2);
        ctx.fillStyle = "#0095DD";
        ctx.fill();
        ctx.closePath();
    }

    function draw() {
        ctx.clearRect(0, 0, canvas.width, canvas.height); // 清除畫面
        drawBall();
        x += dx; // 清除畫面球的位置
        y += dy;
    }

    setInterval(draw, 10); // 每10msec呼叫draw()
    此步驟的完整程式碼:GitHub
    線上測試程式碼:點此在JSFiddle上實際運行並測試或修改程式碼。
    執行結果:


    練習:嘗試改變球移動的速度,或球移動的方向。

  3. 讓球碰到牆壁後反彈
    在前一個步驟球已經可以向斜角方向移動,在這個步驟我們將檢查球是否接觸(撞)到牆壁,也就是所謂的碰撞偵測(collision detection)。如果有碰撞,我們將改變球的行進方向。我們檢查的是球的邊緣是否接觸到牆壁,而不是球的中心,所以增加使用球的半徑ballRadius 來進行計算。球碰到上下左右牆壁的計算方式,是當球的中心加上偏移量與牆的邊緣之間的距離與球的半徑相同時成立,如下圖所示:

    程式碼加入以下片段:

    var ballRadius = 10; //定義一變數 ballRadius 代表球的半徑
    ctx.arc(x, y, ballRadius, 0, Math.PI*2); // 繪製球

    function draw() {
        ...
        if(x + dx > canvas.width-ballRadius || x + dx < ballRadius) { // 右牆或左牆碰撞
            dx = -dx; // 改變運動方向
        }
        if(y + dy > canvas.height-ballRadius || y + dy < ballRadius) { 下牆或上牆碰撞
            dy = -dy;
        }
        ...
    }

    此步驟的完整程式碼:GitHub
    線上測試程式碼:點此在JSFiddle上實際運行並測試或修改程式碼。
    練習:每次撞擊牆壁時,嘗試將球的顏色更改為隨機的顏色。

  4. 球拍和鍵盤控制
    在上個步驟球可以自由地由四邊牆壁反彈了,然後繼續往另一個方向前進,但與使用者
    沒有互動性。讓我們添加一些與使用者的互動:一個可控制的球拍(Paddle),當我們
    按鍵盤的向左鍵或向右鍵,可向左或向右移動球拍。

    程式將會有

    • 繪製球拍的drawPaddle();
    • 處理鍵盤動作需要先註冊按下鍵盤keydown,及放開鍵盤keyup的Event Listener。當接收到向左鍵或向右鍵的事件(Event)時,就會設定leftPressed或rightPressed變數中紀錄的狀態;
    • 在draw()中將根據leftPressed或rightPressed的狀態,移動球拍的位置paddleX,但要注意球拍不能超出左右邊界 。

    上個步驟的程式碼增加以下的內容:

    var paddleHeight = 10;
    var paddleWidth = 75;
    var paddleX = (canvas.width-paddleWidth)/2; // 球拍放置在下牆的中央
    var rightPressed = false; // 右鍵是否按下?
    var leftPressed = false; // 左鍵是否按下?

    document.addEventListener("keydown", keyDownHandler, false);
    document.addEventListener("keyup", keyUpHandler, false);

    function keyDownHandler(e) { // 某一鍵被按下了
        if(e.keyCode == 39) { // 右鍵碼
            rightPressed = true;
        }
        else if(e.keyCode == 37) { // 左鍵碼
            leftPressed = true;
        }
    }
    function keyUpHandler(e) { // 某一鍵放掉了
        if(e.keyCode == 39) {
            rightPressed = false;
        }
        else if(e.keyCode == 37) {
            leftPressed = false;
        }
    }

    function drawPaddle() { // 繪製球拍
        ctx.beginPath();
        ctx.rect(paddleX, canvas.height-paddleHeight, paddleWidth, paddleHeight);
        ctx.fillStyle = "#0095DD";
        ctx.fill();
        ctx.closePath();
    }

    function draw() { // 繪製影格
        ...
        drawPaddle();
        ...
        if(rightPressed && paddleX < canvas.width-paddleWidth) { // 向右且沒超出右界
            paddleX += 7; // 球拍偏移量
        }
        else if(leftPressed && paddleX > 0) {  // 向左且沒超出右界
            paddleX -= 7;
        }
        ...
    }

    此步驟的完整程式碼:GitHub
    線上測試程式碼:點此在JSFiddle上實際運行並測試或修改程式碼。
    練習:使球拍移動更快或更慢,或改變其大小。

  5. 判斷遊戲結束
    看到球從牆上反彈並能夠移動球拍是很有趣的,但除此之外,這個遊戲並沒有任何進展或達到最終目標。從遊戲玩法的角度來看,要能夠有輸有贏,才有樂趣。遊戲中失敗的邏輯很簡單, 如果你的球拍錯過了球,讓球到達遊戲區的底部邊緣,那麼就遊戲結束(Game over)了。這個步驟的重點是:
    • 球拍擊中了球,接著球往另一方向反彈
    • 球拍錯過了球,遊戲就Game over了
    • 重啟遊戲

    在draw()中是允許球在四個牆壁上反彈,讓我們修改為只允許在三個牆壁上反彈 - 左邊,上邊和右邊。假如球錯過球拍而擊中底部邊緣時遊戲將結束。為了保持簡單,程式中使用alert()顯示警告訊息,並使用重新加載頁面reload()重新啟動遊戲,從頭開始。

    上個步驟的程式碼在draw()中增加以下的內容:

    if(y + dy < ballRadius) { // 檢查球的y軸位置超出上邊
        dy = -dy; // 改球的y軸運動方向
    } else if(y + dy > canvas.height-ballRadius) { // 檢查球的y軸位置超出下邊
        if(x > paddleX && x < paddleX + paddleWidth) { // 再檢查球的x軸位置,球在球拍上
            dy = -dy; // 改球的y軸運動方向
        }
        else { // 球的y軸位置超出下邊,且x軸位置在球拍外
            alert("GAME OVER");
            document.location.reload(); // 重新加載頁面
        }
    }

    此步驟的完整程式碼:GitHub
    線上測試程式碼:點此在JSFiddle上實際運行並測試或修改程式碼。
    練習:當球拍打擊到球時,加快球的移動速度。

  6. 建立磚塊區
    到目前為止,我們的遊戲漸漸有趣了!球可以飛來飛去的,也可以用球拍擊球,但很快就變得無聊了!讓我們放一堆磚塊來進行破壞吧!這個步驟的重點是:
    • 宣告一些磚塊相關的變數
    • 使用bricks[][]二維陣列儲存磚塊左上角的座標,其初值為(0,0)
    • 計算磚塊位置的座標,並繪製這些磚塊

    在上個步驟的程式碼中,增加以下的內容:

    // 磚塊相關變數
    var brickRowCount = 3; // 磚塊列數
    var brickColumnCount = 5; // 磚塊行數
    var brickWidth = 75; // 磚塊寬度
    var brickHeight = 20; // 磚塊高度
    var brickPadding = 10; // 磚塊間隔空白
    var brickOffsetTop = 30; // 磚塊離上邊牆距離
    var brickOffsetLeft = 30; // 磚塊離左邊牆距離

    // 所有的磚塊在螢幕上的位置保存在一個二維陣列中,共有c行r列,也將用於以後的碰撞檢測
    var bricks = []; // bricks初值為空陣列
    for(c=0; c<brickColumnCount; c++) { // 行迴圈
        bricks[c] = []; // 初值為空陣列
        for(r=0; r<brickRowCount; r++) { //列迴圈
            bricks[c][r] = { x: 0, y: 0 }; // 每一個磚塊座標的初值為 (0,0)
        }
    }

    // 在螢幕上繪製磚塊
    // 在這裡,我們定義了磚塊的行和列的數量、它們的寬度和高度
    // 以及磚塊之間的間距,因此它們不會彼此接觸,並且與上方牆
    // 和左邊牆有個偏移量,因此它們不會從邊緣開始繪製。
    function drawBricks() {
        for(c=0; c<brickColumnCount; c++) { // 行迴圈
            for(r=0; r<brickRowCount; r++) { // 列迴圈
                // 依據行列位置計算磚塊座標
                var brickX = (c*(brickWidth+brickPadding))+brickOffsetLeft;
                var brickY = (r*(brickHeight+brickPadding))+brickOffsetTop;
                bricks[c][r].x = brickX; // 磚塊x軸座標
                bricks[c][r].y = brickY; // 磚塊y軸座標
                ctx.beginPath();
                ctx.rect(brickX, brickY, brickWidth, brickHeight); // 繪製長方形磚塊
                ctx.fillStyle = "#0095DD"; // 磚塊顏色
                ctx.fill(); // 填滿中心
                ctx.closePath();
            }
        }
    }

    此步驟執行的結果如下圖:

    此步驟的完整程式碼:GitHub
    線上測試程式碼:點此在JSFiddle上實際運行並測試或修改程式碼。
    練習:嘗試更改行或列中的磚數或其位置。

  7. 碰撞偵測
    我們有磚塊出現在螢幕上,但遊戲仍然不是那麼有趣,因為球會穿過磚塊。我們需要添加碰撞檢測,以便可以擊毀磚塊。在没有程式庫的幫助下,可能很難計算圓形的球球是否接觸到矩形的磚塊,為了簡化敎學,在此採用簡單的計算方法。我們將檢查球的中心是否與在任何選定的磚塊矩形區域中,這樣可能不會得到精準的結果,或許有更多複雜的方法可以來執行碰撞檢測,但在此可以方便的學到基本概念。這個步驟中主要有:
    • 碰撞檢測功能
    • 標記磚塊已被碰撞

    在碰撞檢測功能中,將用迴圈檢查所有的磚塊,比較每個磚的位置與球中心的坐標,假如位於其中,將標記status=0。碰撞檢測計算方式如下圖所示:

     

    碰撞檢測程式碼如下,並在drawBricks()中增加 if(bricks[c][r].status == 1)才繪製磚塊。

    function collisionDetection() {
        for(c=0; c<brickColumnCount; c++) { // 行迴圈
            for(r=0; r<brickRowCount; r++) { // 列迴圈
                var b = bricks[c][r];
                if(b.status == 1) { // 此磚還在畫面上
                    if(x > b.x && x < b.x+brickWidth && y > b.y && y < b.y+brickHeight) { // 碰撞?
                        dy = -dy; // 反彈
                        b.status = 0; // 標記此磚已碰撞
                    }
                }
            }
        }
    }

    此步驟執行的結果如下圖:

     

    此步驟的完整程式碼:GitHub
    線上測試程式碼:點此在JSFiddle上實際運行並測試或修改程式碼。
    練習:當球擊中磚塊時,改變球的顏色。

  8. 更新分數和判斷輸贏
    可以破壞磚塊真的很酷,但是為了改進遊戲,可以在每當用戶擊中一塊磚塊時給予獎勵點數,並累加總分。如果你可以看到你在遊戲中的得分數,最終你可以打動你的朋友。在這個步驟中包括下列功能:
    • 計算總分
    • 在畫面上顯示總分

    在JavaScript變數宣告區中增加一個變數來記錄總分:

    var score = 0;

    你還需要一個drawScore()函數,以便顯示分數:

    function drawScore() {
        ctx.font = "16px Arial"; // 字型
        ctx.fillStyle = "#0095DD"; // 總分字體顏色
        ctx.fillText("Score: "+score, 8, 20); // 在座標 (8,20)繪字
    }

    在collisionDetection()函數中添加程式,每當磚塊被摧毀時score的分數增加1分。當所有的磚塊都被摧毀時,簡單的使用alert()顯示獲勝的訊息,贏得遊戲是遊戲中非常重要的時刻。在點擊顯示訊息alert中的按鈕後,將叫用document.location.reload()函數以重新載入頁面,再次啟動新遊戲。在collisionDetection()函數中增加:

                        score++; // 分數加一
                        if(score == brickRowCount*brickColumnCount) {
                            alert("YOU WIN, CONGRATULATIONS!"); // 顯示勝利訊息
                            document.location.reload(); // 重新載入頁面
                        }

    此步驟的完整程式碼:GitHub
    線上測試程式碼:點此在JSFiddle上實際運行並測試或修改程式碼。
    練習:每個磚塊被擊中時增加更多的點數,在結束遊戲時的警告框中增加顯示總分。

  9. 使用滑鼠控制
    遊戲已經完成了,所以讓我們來進一步想一想還有沒有可以改進之處呢?我們已經有了鍵盤控制,也應該可以輕鬆添加使用滑鼠控制。在這個步驟中主要的功能有:
    • mousemove事件的監聽
    • 根據滑鼠游標來更新球拍位置

    聽取滑鼠游標移動比監聽鍵盤按下更為容易,我們只需要在程式碼中增加mousemove事件的監聽器:

    document.addEventListener("mousemove", mouseMoveHandler, false);

    mousemove事件處理函數會根據滑鼠游標在canvas的位置計算球拍位置。在這個函數中,我們先計算出一個relativeX值,它等於滑鼠游標在瀏覽器視窗的水平位置(e.clientX)減去canvas左邊緣和瀏覽器視窗口左邊緣之間的距離(canvas.offsetLeft) - 這等於畫布左邊緣和滑鼠游標之間的距離。 如果relativeX位置大於零並小於畫布寬度,則滑鼠游標在畫布內,並且paddleX位置將被設定為relativeX值減去球拍寬度的一半,也就是球拍左側的位置。將以下函數添加到程式中:

    function mouseMoveHandler(e) {
        var relativeX = e.clientX - canvas.offsetLeft; // 在畫布中的X位置
        if(relativeX > 0 && relativeX < canvas.width) { // 在畫布內
            paddleX = relativeX - paddleWidth/2; // 球拍左側的X座標
        }
    }

    球拍中央現在將跟隨滑鼠游標的位置,但是由於我們將球拍限制在Canvas中移動,所以它不會從兩邊消失。

    此步驟的完整程式碼:GitHub
    線上測試程式碼:點此在JSFiddle上實際運行並測試或修改程式碼。
    練習:調整球拍移動的邊界,因此整個球拍將在畫布的兩個邊緣上可見,而不會有一半球拍消失。

  10. 收尾結束
    在我們寫的任何遊戲中總是有可以改進的餘地。例如,我們可以為玩家提供更多條生命,使得他們可以死一次或兩次,但仍然能夠繼續進行遊戲。我們還可以改進我們的畫面顯示的效率。這個步驟主要功能有:
    • 給玩家更多條生命
    • 改進畫面呈現(render)效率

    給玩家更多條生命在實作是相當直接。在宣告其他變數的地方,讓我們添加一個變數來儲存生命的數量:

    var lives = 3;

    繪製生命計數器 drawLives()與繪製得分計數器drawScore()類似,程式碼如下:

    function drawLives() {
        ctx.font = "16px Arial"; // 字型
        ctx.fillStyle = "#0095DD"; // 須色
        ctx.fillText("Lives: "+lives, canvas.width-65, 20); // 字及其座標
    }

     球碰到下邊牆時,我們將生命數量減1,直到為零才結束遊戲。並且在下一個生命時,重置球和球拍的位置。 所以在draw()函數中修改如下,並且在draw()中增加呼叫 drawLives():

    lives--;
    if(!lives) { // 結束遊戲
        alert("GAME OVER");
        document.location.reload();
    }
    else {
        x = canvas.width/2;
        y = canvas.height-30;
        dx = 2;
        dy = -2;
        paddleX = (canvas.width-paddleWidth)/2;
    }

    使用requestAnimationFrame()改進呈現效率:
    現在讓我們來改進和遊戲機制無關的部份,就是畫面呈現(render)更新的方式效率。使用requestAnimationFrame()函數可以使瀏覽器呈現比我們以前使用setInterval()固定影格數的方法有更好的畫面更新效率,可以有效的降低瀏覽器負載,將程式中原為:

    function draw() {
        ...
        x += dx;
        y += dy;
    }
    setInterval(draw, 10);

    替換為:

    function draw() {
        ...
        x += dx;
        y += dy;
        requestAnimationFrame(draw);
    }
    draw();

    draw()函數現在在requestAnimationFrame()再被叫用,因而循環再次執行,而不是固定的10毫秒畫面速率。我們將交由瀏覽器控制畫面速率,畫面更新速率將改變為根據需要更新圖面時才進行,這將產生比舊的setInterva()方法更高效率,更平滑的動畫循環。

    此步驟的完整程式碼:GitHub
    線上測試程式碼:點此在JSFiddle上實際運行並測試或修改程式碼。
    練習:改變生命的數量和球從球拍上彈起的角度。

 現在!遊戲結束(Game Over)了

 恭喜!你已經完成了本自學課程中所有的步驟。在本文中,你學到畫布操作的基礎知識和簡單的2D遊戲背後的邏輯。現在是學習一些框架(framework)並繼續遊戲開發的好時機。你可以看看這個系列的其他部分,「使用Phaser架框的2D打擊遊戲」或「使用Phaser架框的Cyber Orb」範例教學,你也可以透過MDN(Mozilla Developer Network)遊戲部分取得更多的靈感和知識。

 快樂地編寫遊戲程式吧!

參考資料
2D breakout game using pure JavaScript -
https://developer.mozilla.org/en-US/docs/Games/Tutorials/2D_Breakout_game_pure_JavaScript

Top

  創刊日期:74年10月15日
  發行人 :王大為
    
  總編輯 :江世民
  編輯小組:葛行慧
    
  網站技術:網頁技術及出版組
  出版日期:民國106年1月5日
    
  服務專線:(02)2789-9866
  E-mail:publish@gate.sinica.edu.tw


訂閱與取消訂閱 | 各期通訊 | 中研院資訊服務處 | 中央研究院

本電子報所有文字、圖片版權為中央研究院所有,未經許可請勿轉載。
如對本報有任何意見,請
與我們聯繫。
   
 
 本電子報所有文字、圖片版權為中央研究院所有 。 電子報出版系統由中央研究院資訊服務處開發。