2016年6月6日 星期一

JavaBean 模組化類別 (打包重複功能)

說明,寫兩個檔案:
  1. helloBean.java → 接收一個字串 name,並回傳 “Hello, “ + name
  2. helloBean.jsp → 載入 JavaBean,印出結果。
##ReadMore##
---
前言:
在網頁語言 JSP 及 Servlet 之開發過程中,常常會使用到相同功能的程式,而最快的處理方法就是複製並貼上至其他的頁面,但當程式專案規模變大後,這種方式會導致後續維護及管理的困難,也使不同版本之功能難以維持一致性。
因此可以選擇使用 JavaBean 模組化技術,其主要用來設計特定功能且能夠被使用、復用、替代和連接的副程式,事實上它也只是一般的 Java 類別,但必須遵循 JavaBean API 之規範,例如特定的命名、建構元、方法之規定。

Reference:
國立中山大學程式諮詢網 - 簡介 JavaBean

---
/opt/apache-tomcat-8.0.30/webapps/Test/WEB-INF/src/helloBean.java
package bean;

public class helloBean{
    public String helloBean(String name){
        String message = "Hello, " + name + "!!";
        return message;
    }
}

‧ 編譯檔案為 .class,且檔案位置為:
/opt/apache-tomcat-8.0.30/webapps/Test/WEB-INF/classes/bean/helloBean.class

---
/opt/apache-tomcat-8.0.30/webapps/Test/helloBean.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" %>

<!-- 載入 JavaBean 的語法 -->
<jsp:useBean id='objHello' scope='application' class='bean.helloBean' />

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>demo JavaBeans</title>
</head>
<body>
<%
    String message;
    message = objHello.helloBean("tete");
    out.println(message);
%>
</body>
</html>

---
測試:
http://localhost:8080/Test/helloBean.jsp

寫一個 HTML 傳送表單資料至 JSP

說明:
寫兩個檔案:

  1. request.html → 做一個表單,可傳送資料出去。
  2. request.jsp → 讀取 get 請求,並輸出傳來的資料內容。

---
前言:
HTTP Request 請求,常用的有 GET 及 POST 方法,於網路查詢即可得知兩者差異,這邊就不加說明,直接 codeing 實作。

##ReadMore##
---
兩檔案路徑同樣放至:/opt/apache-tomcat-8.0.30/webapps/Test/

---
request.html
<html>
  <head>>
 
  </head>
   
  <body>
    <form action="request.jsp" method="get">
               請輸入資訊:<input type="text" name="info">
      <input type="submit" value="傳送">
    </form> 
  </body>
</html>

---
request.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>

</head>

<body>
<% 
request.setCharacterEncoding("UTF-8");
//String content=new String(request.getParameter("info").getBytes("UTF-8"));
String content = request.getParameter("info");

if(content == null){
    content = "null";
}else{
    content = new String(request.getParameter("info").getBytes("UTF-8"));       
}
//String content=request.getParameter("info");
%>                                                          
<h2>顯示…</h2>                                              
<h2>收到的訊息:<%=content %></h2>                          
</body>                                                     
</html>

---
測試網址:
http://localhost:8080/Test/request.html

送出表單後,會直接跳轉至
http://localhost:8080/Test/request.jsp

---
也可以硬改網址,直接加入參數及資料給 JSP,例如:
http://localhost:8080/Test/request.jsp?info=hehe

因此也可以發現,從安全性來看,POST (資料參數不會附在網址上)遠優於 GET 求請方式。

Roseapple Pi - 於 Android 之 USB to TTL 連線 + ADB 指令控制

說明:
  1. 使用 USB to TTL 工具,並以 minicom 指令連線至蓮霧派(android)。
  2. 以 ADB 指令控制蓮霧派(android)。
##ReadMore##
---
Step 1. USB to TTL 工具接線:

---
Step 2. 於 Debian 下安裝 minicom 及 ADB 指令:
~$ sudo apt-get install minicom
~$ sudo apt-get install android-tools-adb android-tools-fastboot

---
Step 3. 設定 minicom:
~$ minicom -s

序列埠設定:

按「離開本畫面」可以進入 minicom 連線至蓮霧派 Android 系統文字畫面。
---
Step 4. 設定蓮霧派 ADB TCP port 為 5555:
於 minicom 畫面,控制蓮霧派 Android ADB 指令 -
netcfg → 查看 ip,假設為 192.168.1.100
setprop service.adb.tcp.port 5555 && stop adbd && start adbd

---
Step 5. 網路連線至蓮霧派:
於 Debian 終端機下 ADB 網路連線指令:

adb connect 192.168.1.100

確認裝置有連到,於終端機:
adb devices
---
Step 6. 可以斷開 USB to TTL 連接線路,直接使用終端機透過網路下指令:
adb shell /system/bin/screencap -p /sdcard/screenshot.png → 截圖
adb shell → adb install *.apk → 安裝 apk 檔

查看溫度:
adb -s 192.168.31.124:5555 shell
cat /sys/class/thermal/thermal_zone*/temp

關機:
adb shell reboot -p
adb shell shutdown
adb shell halt

---
其他備註. 使用 `adb connect RoseapplePi.IP` 連接後,可以開啟 Android Studio 軟體找到該裝置,直接燒錄 app 程式。




2016年6月4日 星期六

Apache Tomcat 環境建置

‧ 前言:
Apache Tomcat 是 Apache 軟體基金會下之 Jakarta 項目專案所開發出來的免費開源軟體,內含有 HTTP 伺服器,因此也可以被視作為一個單獨的網頁伺服器;另外主要特色為支援 Java Servlet 及 JavaServer Page (JSP),並且透過 XML 格式之設定檔來管理及控制網頁路徑。

##ReadMore##
---
Step 0. 安裝 Java JDK
可以參考本站文章「設定指令優先權(Java 安裝為例)」,本例使用版本:
~$ java -version

java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)

---
Step 1. 下載檔案
官方下載 Apache Tomcat,
本文使用版本為 apache-tomcat-8.0.30-src.tar.gz

---
Step 2. 解壓縮
於 Linux 系統環境下,通常習慣將第三方協力軟體放置到 “/opt“ 目錄下(需 ROOT)。
~$ sudo tar xfva apache-tomcat-8.0.30-src.tar.gz -C /opt

---
Step 3. 啟動 apache-tomcat 服務
至解壓縮目錄內之 “bin“ 目錄下執行運作服務 Shell Scrip 檔。
~$sudo sh /opt/apache-tomcat-8.0.30/bin/startup.sh

---
Step 4. 測試網頁
開啟瀏覽器鍵入網址 “http://localhost:8080/“,若有正確啟動服務會看到下圖畫面:

---
Step 5. 建立專案
使用 Apache Tomcat 必須遵守其檔案目錄配置的規範,
以路徑 /opt/apache-tomcat-8.0.30/webapps 做為網頁之根目錄 (Root) 開始建立專案目錄。


---
Step 6. 寫 JSP 測試:/opt/apache-tomcat-8.0.30/webapps/Test/hello.jsp
<%@ page contentType="text/html;charset=UTF-8" %>                               
<html>
<head>
    <title>Hello</title><br>
</head>
<body>
    <h3>Input Name</h3>
    <form action="/TestApp/Hello" method="get">
        請輸入姓名:
        <input type="text" name="UserID" />
        <input type="submit" value="Send" />
    </form>
</body>
</html>

---
Step 7-1. 寫 Servlet 測試:/opt/apache-tomcat-8.0.30/webapps/Test/WEB-INF/src/HelloServlet.java
import java.io.*;                                                            
import javax.servlet.*;
import javax.servlet.http.*;

public class HelloServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)
                    throws ServletException, IOException {
        // 下面兩行讓中文字能正確顯示
        response.setContentType("text/html;charset=UTF-8");
        request.setCharacterEncoding("UTF-8");

        PrintWriter out = response.getWriter();
        out.println("<HTML>");
        out.println("<BODY>");
        out.println("<p>Hello! 這是我的第一支 Java servlet 程式。</p>");
        out.println("</BODY>");
        out.println("</HTML>");
  }
}

Step 7-2. 以指令編譯成 .class 檔:/opt/apache-tomcat-8.0.30/webapps/Test/WEB-INF/classes/HelloServlet.class
cd /opt/apache-tomcat-8.0.30/webapps/Test/WEB-INF/src
javac *.java -d ../classes/

Step 7-3. 設定 web.xml:/opt/apache-tomcat-8.0.30/webapps/Test/WEB-INF/web.xml
<servlet>
   <servlet-name>HelloServlet</servlet-name>
   <servlet-class>HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
   <servlet-name>HelloServlet</servlet-name>
   <url-pattern>/HelloServlet</url-pattern>
</servlet-mapping>

---
Step 8-1. 測試 jsp 網址:
http://localhost:8080/Test/hello.jsp

Step 8-2. 測試 servlet 網址:
http://localhost:8080/Test/hello

2016年6月2日 星期四

C#-examination-e

題目要求:
魔術方塊,六種顏色以文字表之。
圖片共十二張:點我下載

##ReadMore##


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using AForge.Imaging.Filters;
using AForge.Imaging.Formats;
using AForge.Imaging;
using System.Drawing.Imaging;
using System.Diagnostics;
using AForge.Math;

namespace examination_e
{
    public partial class Form1 : Form
    {
        Bitmap srcImg, cropImg, confirmImg;
        String knowColor;

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            openFileDialog1.Filter = "All File(*.*)|*.*";
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                srcImg = ImageDecoder.DecodeFromFile(openFileDialog1.FileName);
                pictureBox1.Image = srcImg;
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            listBox1.Items.Clear();
            //因為每張魔術方塊圖大小、位置不定,慢慢抓最大最小值縮減掃描範圍
            int catchX = 250;
            int catchY = 130;
            int catchWidth = 650;
            int catchHeight = 500;

            //第一階段截取圖片,因為每張魔術方塊圖大小、位置不定先截個自訂值(畫 rectangle 慢慢測試得來的)
            Crop cropFilter = new Crop(new Rectangle(catchX, catchY, catchWidth, catchHeight));
            Bitmap scanImg = cropFilter.Apply(srcImg);
            pictureBox3.Image = scanImg;

            Graphics g = Graphics.FromImage(srcImg);
            g.DrawRectangle(new Pen(Color.Red), catchX - 1, catchY - 1, catchWidth + 2, catchHeight + 2);
            pictureBox2.Image = srcImg;

            //Color 陣列用來儲存第一階段截取範圍內全部 colorPixel,容器 +10 避免誤差,造成超出陣列
            Color[,] colorPixel = new Color[catchX + catchWidth + 10, catchY + catchHeight + 10];

            //初始化,魔術方塊區域之座標最大、最小值
            int max_x = 0, max_y = 0, min_x = catchX + catchWidth, min_y = catchY + catchHeight;

            //開始取得第一階段截取範圍全部的 colorPixel
            for (int i = catchX; i < catchX + catchWidth; i++)
            {
                for (int j = catchY; j < catchY + catchHeight; j++)
                {
                    colorPixel[i, j] = srcImg.GetPixel(i, j);
                }
            }

            //掃描第一階段截取之範圍, 取得非黑色的座標之最大、最小座標 max_x, max_y, min_x, min_y
            for (int i = catchX; i < catchX + catchWidth; i++)
            {
                for (int j = catchY; j < catchY + catchHeight; j++)
                {
                    // 設 RGB < 90 為黑色,非魔術方塊區域。
                    if (colorPixel[i, j].R < 90 && colorPixel[i, j].G < 90 && colorPixel[i, j].B < 90) { /*nothing to do*/ }
                    // 第一層過濾,非黑色,則有可能是彩色圖,但有誤差,所以還要第二層過濾。
                    else
                    {
                        // 設 RGB < 90 為黑色,非魔術方塊區域。
                        if (colorPixel[i - 2, j - 2].R < 90 && colorPixel[i - 2, j - 2].G < 90 && colorPixel[i - 2, j - 2].B < 90) { /* nothing to do */ }
                        //第二層過濾,判斷座標 [i-2, j-2] colorPixel 必需不是黑色 (即捕捉連續彩色→但只能捉到魔術方塊左上角座標,右下座標仍有誤差)
                        else
                        {
                            // 設 RGB < 90 為黑色,非魔術方塊區域。
                            if (colorPixel[i + 2, j + 2].R < 90 && colorPixel[i + 2, j + 2].G < 90 && colorPixel[i + 2, j + 2].B < 90) { /* nothing to do */ }
                            //第三層過濾,判斷座標 [i+2, j+2] colorPixel 必需不是黑色 (即捕捉連續彩色→測試後可以正確抓到魔術方塊完整範圍)
                            else
                            {
                                // 抓魔術方塊區域之座標最大、最小值
                                if (max_x < i)
                                    max_x = i;
                                if (max_y < j)
                                    max_y = j;
                                if (min_x > i)
                                    min_x = i;
                                if (min_y > j)
                                    min_y = j;
                            }

                        }
                    }
                }
            }

            //得到魔術方塊區域之最大、最小座標 max_x, max_y, min_x, min_y,算差值得到魔術方塊之 Height= calcH, Width=calcW
            int calcW = max_x - min_x;
            int calcH = max_y - min_y;

            //做記號至 srcImg 測試確認用
            g.DrawRectangle(new Pen(Color.Red), min_x, min_y, calcW, calcH);
            textBox1.Text = "BottomRight=(" + max_x + ", " + max_y + ")";
            textBox2.Text = "TopLeft=(" + min_x + ", " + min_y + ")";
            textBox3.Text = "width=" + calcW + ", height=" + calcH;

            //第二階段截取圖片,得到完整魔術方塊的區域 = cropImg
            Crop cropFilter2 = new Crop(new Rectangle(min_x, min_y, calcW, calcH));
            cropImg = cropFilter2.Apply(srcImg);

            //魔術方塊的區域印至 pictureBox3 再確認
            pictureBox3.Image = cropImg;

            /*
            //手動測試用
            int jjj = 0;
            int iii = 2;
            Crop cropFilterTest = new Crop(new Rectangle(iii * calcW / 3, jjj * calcH / 3, calcW / 3, calcH / 3));
            confirmImg = cropFilterTest.Apply(cropImg);
            pictureBox4.Image = confirmImg;
             */

            //掃描魔術方塊區域
            for (int jj = 0; jj < 3; jj++)
            {
                for (int ii = 0; ii < 3; ii++)
                {
                    //第三階段截取,割成 3×3, 每一格單位: Width=calcH/3, Height=calcH/3,以 for-loop 掃描 
                    Crop cropFilter3 = new Crop(new Rectangle(ii * calcW / 3, jj * calcH / 3, calcW / 3, calcH / 3));
                    confirmImg = cropFilter3.Apply(cropImg);

                    //傳送單塊顏色中心點之 RGB 判別顏色
                    Color confirmPixel = confirmImg.GetPixel(confirmImg.Width / 2, confirmImg.Height / 2);
                    //寫一個 function confirmColor 內有色表做顏色確認
                    confirmColor(confirmPixel.R, confirmPixel.G, confirmPixel.B);
                    listBox1.Items.Add("(" + jj + ", " + ii + ") = " + knowColor);
                    //listBox1.Items.Add("R,G,B = " +confirmPixel.R + "," + confirmPixel.G + "," + confirmPixel.B);
                    listBox1.Items.Add("");
                }
                listBox1.Items.Add("-----------------");
            }
            pictureBox2.Image = srcImg;     
        }

        public void confirmColor(int R, int G, int B)
        {
            //Blue
            if (R < 40 && G < 50 && B > 70 && B < 150)
                knowColor = "Blue";
            //Yellow
            else if (R > 200 && G > 170 && B > 50 && B < 96)
                knowColor = "Yellow";
            //Green
            else if (R < 80 && G > 50 && G < 160 && B > 40 && B < 100)
                knowColor = "Green";
            //Orange
            else if (R > 175 && G > 55 && G < 115 && B < 68)
                knowColor = "Orange";
            //Red
            else if (R > 100 && R < 200 && G < 55 && B < 50)
                knowColor = "Red";
            //White
            else if (R > 170 && G > 179 && B > 170)
                knowColor = "White";
            else
            {
                knowColor = "unknow";
            }
        }
    }
}

C#-examination-d

題目要求:
使用textbox show出各個blob的中心點座標
圖片:1-1.bmp

##ReadMore##


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using AForge.Imaging;
using AForge.Imaging.Formats;
using AForge.Imaging.Filters;
using AForge.Math;
using AForge.Video;

namespace examination_d
{
    public partial class Form1 : Form
    {
        Bitmap srcImg;

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            srcImg = ImageDecoder.DecodeFromFile("1-1.bmp");
            pictureBox1.Image = srcImg;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            int largestarea, ii, blobcount, totalarea, avearea;
            Grayscale grayFilter = new Grayscale(0.2125, 0.7154, 0.0721);
            Bitmap grayImg = grayFilter.Apply(srcImg);
            pictureBox2.Image = grayImg;

            Threshold thresFilter = new Threshold(254);
            Bitmap bimage = thresFilter.Apply(grayImg);
            pictureBox3.Image = bimage;

            // create an instance of blob counter algorithm
            BlobCounterBase bc = new BlobCounter();
            // set filtering options
            bc.FilterBlobs = true;
            bc.MinWidth = 5;
            bc.MinHeight = 5;
            // set ordering options
            bc.ObjectsOrder = ObjectsOrder.Size;
            // process binary image
            bc.ProcessImage(bimage);
            Blob[] blobs = bc.GetObjectsInformation();
            // extract the biggest blob

            largestarea = blobs[0].Area;
            textBox1.Text = largestarea.ToString();
            blobcount = bc.ObjectsCount;
            textBox2.Text = bc.ObjectsCount.ToString();
            textBox7.Text = blobs[0].CenterOfGravity.ToString();

            totalarea = 0;
            for (ii = 0; ii < blobcount; ii++)
            {
                totalarea = totalarea + blobs[ii].Area;

                listBox1.Items.Add(blobs[ii].Area.ToString());

            }

            for (ii = 0; ii < blobcount; ii++)
            {
                listBox2.Items.Add("blobs[" + ii + "] = (" + Convert.ToInt16(blobs[ii].CenterOfGravity.X).ToString() + ", " + Convert.ToInt16(blobs[ii].CenterOfGravity.Y).ToString() + ")");
            }

            textBox4.Text = totalarea.ToString();

            avearea = totalarea / blobcount;
            textBox5.Text = avearea.ToString();

            Invert filterinv = new Invert();
            Bitmap invimg = filterinv.Apply(bimage);
            pictureBox4.Image = invimg;

            // create filter
            Subtract filtersub = new Subtract(invimg);
            // apply the filter
            Bitmap blobimg = filtersub.Apply(grayImg);
            pictureBox5.Image = blobimg;


            // gather statistics
            ImageStatistics stat = new ImageStatistics(blobimg);
            // get red channel's histogram
            Histogram gray = stat.Gray;
            int blobimgarea = stat.PixelsCountWithoutBlack;
            double blobmean = gray.Mean * blobimg.Height * blobimg.Width / blobimgarea;
            textBox6.Text = blobmean.ToString();

        }

    }
}

C#-examination-c

題目要求:
算板手(p5)的面積與中間寬度
圖片:p5.jpg

##ReadMore##


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using AForge.Imaging;
using AForge.Imaging.Filters;
using AForge.Imaging.Formats;
using AForge.Math;

namespace examination_c
{
    public partial class Form1 : Form
    {
        Bitmap srcImg, tempImg;
        int x = 400, y1 = 100, y2 = 500;

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            srcImg = ImageDecoder.DecodeFromFile("p5.jpg");
            tempImg = new Bitmap(srcImg);
            pictureBox1.Image = srcImg;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Grayscale grayFilter = new Grayscale(0.2125, 0.7154, 0.0721);
            tempImg = grayFilter.Apply(tempImg);

            OtsuThreshold otsuFilter = new OtsuThreshold();
            tempImg = otsuFilter.Apply(tempImg);

            Invert invFilter = new Invert();
            tempImg = invFilter.Apply(tempImg);

            FillHoles holeFilter = new FillHoles();
            holeFilter.MaxHoleHeight = 100;
            holeFilter.MaxHoleWidth = 100;
            holeFilter.CoupledSizeFiltering = false;
            tempImg = holeFilter.Apply(tempImg);

            pictureBox2.Image = tempImg;
        }

        private void button3_Click(object sender, EventArgs e)
        {
            Graphics g = Graphics.FromImage(srcImg);
            g.DrawLine(new Pen(Color.Red), new Point(x, y1), new Point(x, y2));
            pictureBox1.Image = srcImg;
        }

        private void button4_Click(object sender, EventArgs e)
        {
            Bitmap imgtwo = new Bitmap(tempImg);
            Graphics g2 = Graphics.FromImage(imgtwo);

            int[,] point = new int[x + 5, y2 + 5];
            int count = 0;
            int[] value = new int[2];

            for (int y = y1; y < y2; y++)
            {
                Color pixelColor = imgtwo.GetPixel(x, y);
                point[x, y] = pixelColor.R;
            }

            for (int y = y1; y < y2; y++)
            {
                if (point[x, y] < 20)
                {
                    if (point[x, y] != point[x, y - 1] || point[x, y] != point[x, y + 1])
                    {
                        value[count] = y;
                        count++;
                    }
                }
            }

            listBox1.Items.Add("第一點座標 = (" + x + ", " + value[0] + ")");
            listBox1.Items.Add("第二點座標 = (" + x + ", " + value[1] + ")");
            listBox1.Items.Add("板手寬度 = " + (value[1] - value[0]).ToString());
            g2.DrawLine(new Pen(Color.Red), new Point(x, value[0]), new Point(x, value[1]));
            pictureBox2.Image = imgtwo;
        }

        private void button5_Click(object sender, EventArgs e)
        {
            // create filter
            BlobsFiltering filter = new BlobsFiltering();
            // configure filter
            filter.CoupledSizeFiltering = true;
            filter.MinWidth = 1;
            filter.MinHeight = 1;
            // apply the filter
            Bitmap dstImage = filter.Apply(tempImg);
            //pictureBox2.Image = dstImage;


            BlobCounterBase bc = new BlobCounter();
            bc.FilterBlobs = true;
            bc.MinWidth = 1;
            bc.MinHeight = 1;
            bc.ObjectsOrder = ObjectsOrder.Area;

            bc.ProcessImage(dstImage); // process binary image
            Blob[] blobs = bc.GetObjectsInformation();

            textBox1.Text = "Blob Count = " + bc.ObjectsCount.ToString();//總個數

            int totalarea = 0;
            for (int ii = 0; ii < bc.ObjectsCount; ii++)
            {
                totalarea = totalarea + blobs[ii].Area;
                listBox2.Items.Add("Blob[" + ii + "] = " + blobs[ii].Area.ToString());
            }
            listBox2.Items.Add("Total Area = " + totalarea);
        }
    }
}

C#-examination-b

題目要求:
掃描Bracket1圖片的 (a)兩個寬度與 (b)中間空隙之寬度
圖片:Bracket1.bmp

##ReadMore##


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using AForge.Imaging;
using AForge.Imaging.Filters;
using AForge.Imaging.Formats;

namespace examination_b
{
    public partial class Form1 : Form
    {
        Bitmap srcImg, tempImg, bwImg;

        int x = 400, y1 = 100, y2= 400;
        int[] y_value = new int[4];

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            srcImg = ImageDecoder.DecodeFromFile("Bracket1.bmp");
            tempImg = new Bitmap(srcImg);
            pictureBox1.Image = srcImg;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Graphics g = Graphics.FromImage(srcImg);
            g.DrawLine(new Pen(Color.Red), new Point(x, y1), new Point(x, y2));

            pictureBox1.Image = srcImg;
        }

        private void button3_Click(object sender, EventArgs e)
        {
            Grayscale grayFilter = new Grayscale(0.2125, 0.7154, 0.0721);
            Bitmap grayImg = grayFilter.Apply(tempImg);

            OtsuThreshold otsuFilter = new OtsuThreshold();
            bwImg = otsuFilter.Apply(grayImg);

            pictureBox2.Image = bwImg;
        }

        private void button4_Click(object sender, EventArgs e)
        {
            int[,] point = new int[x+5, y2+5];
            int count = 0;

            for (int y = y1; y < y2; y++)
            {
                Color pixelColor = bwImg.GetPixel(x, y);
                point[x, y] = pixelColor.R;
            }

            for (int y = y1; y < y2; y++)
            {
                if (point[x, y] < 20)
                {
                    if (point[x, y] != point[x, y - 1] || point[x, y] != point[x, y + 1])
                    {
                        y_value[count] = y;
                        count++;
                        listBox1.Items.Add("(" + x + ", " + y + ")");
                    }
                }
            }
        }

        private void button5_Click(object sender, EventArgs e)
        {
            Bitmap imgtwo = new Bitmap(bwImg);
            Graphics g2 = Graphics.FromImage(imgtwo);

            g2.DrawLine(new Pen(Color.Yellow), new Point(x, y_value[0]), new Point(x, y_value[1]));
            listBox2.Items.Add("上面寬度(Yellow) = " + (y_value[1] - y_value[0]).ToString());

            g2.DrawLine(new Pen(Color.Purple), new Point(x, y_value[1]), new Point(x, y_value[2]));
            listBox2.Items.Add("中間空隙(Purple) = " + (y_value[2] - y_value[1]).ToString());

            g2.DrawLine(new Pen(Color.Green), new Point(x, y_value[2]), new Point(x, y_value[3]));
            listBox2.Items.Add("上面寬度(Green) = " + (y_value[3] - y_value[2]).ToString());

            pictureBox2.Image = imgtwo;
        }
    }
}

C#-examination-a

題目要求:
將圖切成 3*5 份去掃描,將對比最高的圖顯示出來 (找瑕疵)
圖片:L02.jpg


##ReadMore##

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using AForge.Imaging.Formats;
using AForge.Imaging.Filters;
using System.Diagnostics;
using AForge.Imaging;
using AForge.Math;

namespace examination_a
{
    public partial class Form1 : Form
    {
        Bitmap srcImg, grayImg, cropImg;

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            srcImg = ImageDecoder.DecodeFromFile("L02.jpg");
            pictureBox1.Image = srcImg;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Crop cropFilter = new Crop(new Rectangle(1, 1, 2560, 2560));
            Bitmap templateImg = cropFilter.Apply(srcImg);

            Grayscale grayFilter = new Grayscale(0.2125, 0.7154, 0.0721);
            grayImg = grayFilter.Apply(templateImg);

            pictureBox3.Image = grayImg;
        }

        private void button3_Click(object sender, EventArgs e)
        {
            Graphics g = Graphics.FromImage(srcImg);
            Stopwatch stopWatch = new Stopwatch();
            stopWatch.Reset();
            stopWatch.Start();

            double maxStdDev = -1;
            int ii = 0, jj = 0;

            for (int i = 0; i < 5; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    Crop matchCropFilter = new Crop(new Rectangle(i * 512, j * 512, 512, 512));
                    cropImg = matchCropFilter.Apply(grayImg);

                    g.DrawRectangle(new Pen(Color.White), i * 512, j * 512, 512, 512);

                    ImageStatistics stat = new ImageStatistics(cropImg);
                    Histogram gray = stat.Gray;

                    listBox1.Items.Add("(" + i + ", " + j + ") = " + gray.StdDev.ToString());

                    if (gray.StdDev > maxStdDev)
                    {
                        maxStdDev = gray.StdDev;
                        ii = i;
                        jj = j;
                    }
                }
            }

            g.DrawRectangle(new Pen(Color.Red), ii * 512, jj * 512, 512, 512);
            textBox2.Text = maxStdDev.ToString();
            pictureBox2.Image = srcImg;

            TimeSpan ts = stopWatch.Elapsed;
            textBox1.Text = ts.ToString();
        }
    }
}

C#-examination-4

題目要求:

  • button1: 讀圖 lena 與 lena_2
  • button2: 求 lena 與 lena_2之差異 difference
  • button3: 將差異轉成灰階圖
  • button4: 利用影像增強手法將 button3 之差異強化
##ReadMore##

比較圖一:lena



比較圖二:lena_2


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using AForge.Imaging;
using AForge.Imaging.Formats;
using AForge.Imaging.Filters;
using AForge.Video;
using System.Diagnostics;
using System.Drawing.Imaging;
using AForge.Math;

namespace examination_4
{
    public partial class exam4 : Form
    {
        Bitmap img1, img2, catchImg, grayImg;
        

        public exam4()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            openFileDialog1.Filter = "所有檔案(*.*)|*.*";
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                img1 = ImageDecoder.DecodeFromFile(openFileDialog1.FileName);
                pictureBox1.Image = img1;
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            openFileDialog2.Filter = "所有檔案(*.*)|*.*";
            if (openFileDialog2.ShowDialog() == DialogResult.OK)
            {
                img2 = ImageDecoder.DecodeFromFile(openFileDialog2.FileName);
                pictureBox2.Image = img2;
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            img1 = (Bitmap)pictureBox1.Image;
            img2 = (Bitmap)pictureBox2.Image;
        }

        private void button3_Click(object sender, EventArgs e)
        {
            // 取兩圖長、寬最小值
            int imgWidth = Math.Min(img1.Width, img2.Width);
            int imgHeight = Math.Min(img1.Height, img2.Height);
            int minX = imgWidth;
            int minY = imgHeight;
            int maxX = 0;
            int maxY = 0;

            // 比較的 Pixel 範圍
            for (int x = 0; x < imgWidth; x++)
            {
                for (int y = 0; y < imgHeight; y++)
                {
                    // 比較兩圖 Pixel
                    if(img1.GetPixel(x,y).Equals(img2.GetPixel(x,y)))
                    {
                        // 相同 Pixel ,維持原圖                        
                    }
                    else
                    {
                        // 不相同

                        // 取差異圖最左上點
                        if (minX > x)
                            minX = x;
                        if (minY > y)
                            minY = y;

                        // 取差異圖最右下點
                        if (maxX < x)
                            maxX = x;
                        if (maxY < y)
                            maxY = y;
                    }
                }
            }
            
            catchDiff(minX, minY, maxX, maxY);
            drawDiffFrame(minX, minY, maxX, maxY);

            pictureBox1.Image = img1;
            pictureBox2.Image = img2;
        }

        // 補捉兩圖不同點於 pictureBox3
        private void catchDiff(int topLeft_X, int topLeft_Y, int bottomRight_X, int bottomRight_Y)
        {
            Crop cropFilter = new Crop(new Rectangle(topLeft_X - 5, topLeft_Y - 5, bottomRight_X - topLeft_X + 10, bottomRight_Y - topLeft_Y + 10));
            catchImg = cropFilter.Apply(img2);
            pictureBox3.Image = catchImg;
        }

        // 於原圖及比對圖畫出框,框出差異
        private void drawDiffFrame(int topLeft_X, int topLeft_Y, int bottomRight_X, int bottomRight_Y)
        {
            using (Graphics g = Graphics.FromImage(img1))
            {
                g.DrawRectangle(new Pen(Color.Red), topLeft_X - 6, topLeft_Y - 6, bottomRight_X - topLeft_X + 12, bottomRight_Y - topLeft_Y + 12);
            }
            using (Graphics g = Graphics.FromImage(img2))
            {
                g.DrawRectangle(new Pen(Color.Red), topLeft_X - 6, topLeft_Y - 6, bottomRight_X - topLeft_X + 12, bottomRight_Y - topLeft_Y + 12);
            }
        }

        // 影像灰階
        private void button4_Click(object sender, EventArgs e)
        {
            Grayscale grayFilter = new Grayscale(0.2125, 0.7154, 0.0721);
            grayImg = grayFilter.Apply(catchImg);
            pictureBox3.Image = grayImg;
        }

        // 續影像灰階,再影像強化處理
        private void button5_Click(object sender, EventArgs e)
        {
            Bitmap thsImg;
            Threshold thFilter = new Threshold(23);
            thsImg = thFilter.Apply(grayImg);
            pictureBox3.Image = thsImg;
        }

    }
}

C#-examination-3

題目要求:

  • 讀圖。
  • show 出圖之大小,包含 width and height。
  • show 出中間點 width/2 and height/2 之 RGB 值。
##ReadMore##

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using AForge.Imaging;
using AForge.Imaging.Filters;
using AForge.Imaging.Formats;

namespace examination_3
{
    public partial class exam3 : Form
    {

        Bitmap img;
        Color colorPixel;

        public exam3()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void openFileDialog1_FileOk(object sender, CancelEventArgs e)
        {
            
        }

        private void button1_Click(object sender, EventArgs e)
        {
             OpenFileDialog readImg = new OpenFileDialog();
             if (readImg.ShowDialog() == DialogResult.OK)
             {
                 img = new Bitmap(readImg.FileName);
                 pictureBox1.Image = img;

                 textBox1.Text = img.Width.ToString();
                 textBox2.Text = img.Height.ToString();

                 colorPixel = img.GetPixel(img.Width / 2, img.Height / 2);
                 textBox3.Text = colorPixel.R.ToString();
                 textBox4.Text = colorPixel.G.ToString();
                 textBox5.Text = colorPixel.B.ToString();

             }
        }
    }
}

C#-examination-2

題目要求:
  • button1: 做積分
  • steps數目10000
  • show出結果與執行時間(耗時)
##ReadMore##

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;

namespace examination_2
{
    public partial class exam2 : Form
    {

        Stopwatch stopWatch = new Stopwatch();

        public exam2()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            // Start Watch
            stopWatch.Reset();
            stopWatch.Start();

            // Integration
            int steps = 10000;
            double ans = 0;
            double x, fx;
            double en = 4 * Math.PI;
            double bn = 0;
            double parti = (en - bn) * 1 / steps;

            for (int i = 0; i < steps; i++)
            {
                x = bn + parti * i;
                fx = x * x * x * Math.Sin(2 * x) * Math.Cos(x);
                ans = ans + fx * parti;
            }

            // Stop Watch
            stopWatch.Stop();

            // Show timesapn and Answer
            TimeSpan ts = stopWatch.Elapsed;
            textBox1.Text = ts.ToString();
            textBox2.Text = ans.ToString();
            
        }

        private void pictureBox1_Click(object sender, EventArgs e)
        {

        }

        private void textBox2_TextChanged(object sender, EventArgs e)
        {

        }
    }
}

C#-examination-1

題目要求:
  1. 做 button1 → 讀圖。
  2. 做 button2 → 從左上角劃一綠線,至右下角。
  3. 做 button3 → 中間部位畫一50X150之紅色四邊形。
  4. 做 button4 → 存檔。

##ReadMore##

測試圖檔:https://sites.google.com/site/p501labsite/microsoft-virtual-studio/lena.png?attredirects=0&d=1


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using AForge.Imaging;
using AForge.Imaging.Filters;
using AForge.Imaging.Formats;


namespace examination_1
{
    public partial class exam1 : Form
    {
        //statement
        Bitmap img_L, img_R;
        Color colorPixel;
        int[,] maR = new int[1024, 1024];
        int[,] maG = new int[1024, 1024];
        int[,] maB = new int[1024, 1024];

        public exam1()
        {
            InitializeComponent();
        }

        //Read File
        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog readImg = new OpenFileDialog();
            if (readImg.ShowDialog() == DialogResult.OK)
            {
                img_L = new Bitmap(readImg.FileName);
                img_R = img_L;
                pictureBox1.Image = img_L;
                pictureBox2.Image = img_L;

                // 儲存原圖 colorPixel 
                for (int i = 0; i < img_L.Width; i++)
                {
                    for (int j = 0; j < img_L.Height; j++)
                    {
                        colorPixel = img_L.GetPixel(i, j);
                        maR[i, j] = colorPixel.R;
                        maG[i, j] = colorPixel.G;
                        maB[i, j] = colorPixel.B;
                    }
                }
            }
        }

        //Diagonal Top-left to Bottom-right
        private void button2_Click(object sender, EventArgs e)
        {
            // 對角線之 colorPixel
            for (int i = 0; i <= img_L.Height; i++)
            {
                maR[i, i] = 0;
                maG[i, i] = 0;
                maB[i, i] = 0;
            }

            // paint diagonal
            for (int i = 0; i < img_L.Width; i++)
            {
                for (int j = 0; j < img_L.Height; j++)
                {
                    Color diagonalPixel = Color.FromArgb(maR[i, j], maG[i, j], maB[i, j]);
                    img_R.SetPixel(i, j, diagonalPixel);
                }
            }
            pictureBox2.Image = img_R;

        }

        //Rectangle 50 x 150
        private void button3_Click(object sender, EventArgs e)
        {
            int drawWidth = 50;
            int drawHeight = 150;

            // 中間繪圖點
            int originX = img_L.Width / 2 - drawWidth / 2;
            int originY = img_L.Height / 2 - drawHeight / 2;

            for (int i = originX; i <= originX + drawWidth; i++)
            {
                for (int j = originY; j <= originY + drawHeight; j++)
                {
                    maR[i, j] = 255;
                    maG[i, j] = 0;
                    maB[i, j] = 0;
                }
            }

            // paint rectangle
            for (int i = 0; i < img_L.Width; i++)
            {
                for (int j = 0; j < img_L.Height; j++)
                {
                    Color rectanglePixel = Color.FromArgb(maR[i, j], maG[i, j], maB[i, j]);
                    img_R.SetPixel(i, j, rectanglePixel);
                }
            }
            pictureBox2.Image = img_R;
        }

        //Save File
        private void button4_Click(object sender, EventArgs e)
        {
            saveFileDialog1.FileName = @"img.bmp";
            saveFileDialog1.Filter = "Bitmap File(*.bmp) | *.bmp";
            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                img_R.Save(saveFileDialog1.FileName);
            }

        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }
    }
}


2016年4月27日 星期三

Xilinx - MorFPGA

官方下載網站:

http://www.xilinx.com/support/download/index.html/content/xilinx/en/downloadNav/design-tools.html

校內ftp:

Linux : wget ftp://120.117.74.22/ise.tar

解開並執行圖形安裝程式
用 root 執行 ./xsetup

Accept License Agreement
勾 accept

在 Select Products to Install
選擇 ISE WebPACK

在 Select Installation Options
把 install Cable Drivers 打勾


在 Select Destination Directory
選擇要儲存的位置

最後按 Install 等它安裝完畢
---------------------

完畢後

把 Platform Cable USB 插上電腦
紅燈表示 Cable Driver 沒有裝好
綠燈表示有裝好

以下是顯示紅燈時要執行的步驟

Install Xilinx USB Cable Drivers 14.7 on Debian

apt-get install fxload

Create /etc/udev/rules.d/xusbdfwu.rules with the following content;

# version 0003
ATTRS{idVendor}=="03fd", ATTRS{idProduct}=="0008", MODE="666"
SUBSYSTEM=="usb", ACTION=="add", ATTRS{idVendor}=="03fd", ATTRS{idProduct}=="0007", RUN+="/sbin/fxload -v -t fx2 -I /opt/Xilinx/14.7/ISE_DS/ISE/bin/lin64/xusbdfwu.hex -D $tempnode"
SUBSYSTEM=="usb", ACTION=="add", ATTRS{idVendor}=="03fd", ATTRS{idProduct}=="0009", RUN+="/sbin/fxload -v -t fx2 -I /opt/Xilinx/14.7/ISE_DS/ISE/bin/lin64/xusb_xup.hex -D $tempnode"
SUBSYSTEM=="usb", ACTION=="add", ATTRS{idVendor}=="03fd", ATTRS{idProduct}=="000d", RUN+="/sbin/fxload -v -t fx2 -I /opt/Xilinx/14.7/ISE_DS/ISE/bin/lin64/xusb_emb.hex -D $tempnode"
SUBSYSTEM=="usb", ACTION=="add", ATTRS{idVendor}=="03fd", ATTRS{idProduct}=="000f", RUN+="/sbin/fxload -v -t fx2 -I /opt/Xilinx/14.7/ISE_DS/ISE/bin/lin64/xusb_xlp.hex -D $tempnode"
SUBSYSTEM=="usb", ACTION=="add", ATTRS{idVendor}=="03fd", ATTRS{idProduct}=="0013", RUN+="/sbin/fxload -v -t fx2 -I /opt/Xilinx/14.7/ISE_DS/ISE/bin/lin64/xusb_xp2.hex -D $tempnode"
SUBSYSTEM=="usb", ACTION=="add", ATTRS{idVendor}=="03fd", ATTRS{idProduct}=="0015", RUN+="/sbin/fxload -v -t fx2 -I /opt/Xilinx/14.7/ISE_DS/ISE/bin/lin64/xusb_xse.hex -D $tempnode"

把 /opt/Xilinx/14.7/ISE_DS/ISE/bin/lin64/xusbdfwu.hex
改成剛剛所安裝的路徑, 共六個.

然後執行
# udevadm control --reload-rules 

在把 Cable USB 重新插入, 應該會變綠色.

----------------------------

啟動 ISE 軟體

cd /Xilinx/14.7/ISE_DS, 你所安裝的路徑

source settings64.sh

ise 需要 Licence

我的 Licence
wget ftp://120.117.74.22/Xilinx.lic

執行 ise 後, 出現 Xilinx Licence Configuration Manager

選擇 Locate Existing License(s)
選擇 Xilinx.lic
----------------------

New Project
**晶片設定**
Family -> Spartan3
Device -> XC3S1500
Package -> FG676

從 project 開啟燒入程式
Configure Target Device展開 -> Generate Target PROM/ACE File
從 project 開啟設定接腳的程式
User Constraints展開 -> I/O Pin Planning (PlanAhead) - Post-Synthesis

指令直接輸入 impact 開啟燒入程式, 可以直接燒入 .bit .mcs 檔



2016年3月23日 星期三

openCV -Step1 Display image with C/C++

1.編寫一個 C/C++ 語言程式檔 displayimage.cpp,程式碼如下:
#include <stdio.h>
#include <opencv2/opencv.hpp>

using namespace cv;

int main(int argc, char **argv )
{
    if ( !argc[2] )
    {
        printf("usage: DisplayImage <Image_Path>\n");
        return -1;
    }

    Mat image;
    image = imread( argv[1], 1 );

    if ( !image.data )
    {
        printf("No image data \n");
        return -1;
    }
    namedWindow("DisplayImage", WINDOW_AUTOSIZE );
    imshow("DisplayImage", image);

    waitKey(0);

    return 0;
}

2.編寫一個 CMakeLists.txt 檔,程式碼如下:
cmake_minimum_required(VERSION 2.8)
project( DisplayImage )
find_package( OpenCV REQUIRED )
add_executable( DisplayImage DisplayImage.cpp )
target_link_libraries( DisplayImage ${OpenCV_LIBS} )

3.將1、2點的檔案和任意圖檔(XXX.png)放在同一個目錄 displayimage 底下,執行 cmake .,之後執行 make :

$ cmake .
$ make

執行最後會顯示下列訊息:
...
-- Build files have been written to: /home/<username>/.../DisplayImage
4.會出現一個叫 DisplayImage 的可執行檔,並執行下列指令:

$ ./DisplayImage XXX.png

即可用opencV 顯示圖片



參考資料:
www.google.com
http://www.bogotobogo.com/OpenCV/opencv_3_tutorial_ubuntu14_install_cmake.php
http://blog.csdn.net/poem_qianmo/article/details/20537737

2016年3月16日 星期三

openCV -Step0 Building openCV on Debian Linux

1.至 openCV 官方網站下載函式庫,裏面有很多種版本,我裝的是最新版 VERSION 3.4:

   從openCV的GitHub下載檔案,指令如下: 
    $ git clone https://github.com/opencv/opencv.git


2.將電腦更新並且下載需要的套件:
# apt-get update
# apt-get install libopencv-dev build-essential checkinstall cmake pkg-config yasm libtiff5-dev libjpeg-dev libjasper-dev libavcodec-dev libavformat-dev libswscale-dev libdc1394-22-dev libxine2-dev libgstreamer0.10-dev libgstreamer-plugins-base0.10-dev libv4l-dev python-dev python-numpy libtbb-dev libqt4-dev libgtk2.0-dev libfaac-dev libmp3lame-dev libopencore-amrnb-dev libopencore-amrwb-dev libtheora-dev libvorbis-dev libxvidcore-dev x264 v4l-utils ffmpeg

3.將 openCV 官網抓下來的 opencv-3.4.zip 解壓縮,進入 opencv-3.4裡面建立 release 資料夾,再 release 裡面執行一串cmake 程序:
    $ cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D WITH_TBB=ON -D BUILD_NEW_PYTHON_SUPPORT=ON -D WITH_V4L=ON -D INSTALL_C_EXAMPLES=ON -D INSTALL_PYTHON_EXAMPLES=ON -D BUILD_EXAMPLES=ON -D WITH_QT=ON -D WITH_OPENGL=ON ..

    執行最後會顯示下列訊息:
    ...
    -- Build files have been written to: /home/<username>/.../opencv-3.1.0/release

    4.接著執行 make 和 make install 即可完成 openCV的環境建置:

    $ make
    # make install

    5.參考網址:

    2016年1月13日 星期三

    SDL - Step7俄羅斯方塊


    螢幕截圖:

    #include<stdbool.h>
    #include<stdio.h>
    #include<stdlib.h>
    #include<time.h>
    #include<math.h>
    #include"SDL/SDL.h"
    #define height 400
    #define width 400
    #define speed 20
    struct brick
    {
     SDL_Rect a;
     int appearance;//the number of box
     struct brick *next;
    };
    typedef struct brick BRICK;
    //方塊初始座標
    int O[8]={80,100,100,80,20,20,0,0};
    int I[8]={80,80,80,80,60,40,20,0};
    int J[8]={100,80,80,80,0,40,20,0};
    int L[8]={100,80,80,80,40,40,20,0};
    int S[8]={100,100,80,80,40,20,20,0};
    int Z[8]={80,80,100,100,40,20,20,0};
    int T[8]={100,80,80,80,20,40,20,0};
    void Create(int R[],int c);
    void Button(void);
    void Overlapping(void);
    void Boundary(void);
    void Correct(void);
    void GameOver(void);
    void JudgePositionAfterCorrect(void);
    void Rotation(void);
    void MoveToDown(BRICK *deliver);
    void LeftAndRight(void);
    void Drop(void);
    void Cancellation(void);
    BRICK *first,*current,*previous,*temp;
    bool running=true,move=false,correcting=false,DN=false,LR=false,dropping=false;
    int dx=20,dy=speed,number=0,acount=0,cycle=0,i,j,p,Cx,Cy,J1,I1,J2,I2,ee=0;
    int main()
    {
     printf("=======================\n");
     printf("= SPACE - high down   =\n");
     printf("= UP    - rotate      =\n");
     printf("= DOWN  - slow down   =\n");
     printf("= LEFT  - left        =\n");
     printf("= RIGHT - right       =\n");
     printf("=======================\n");
     SDL_Init(SDL_INIT_EVERYTHING);
     SDL_Surface* screen;
     screen=SDL_SetVideoMode(width,height,32,SDL_SWSURFACE);
     SDL_WM_SetCaption("---Tetris---",NULL);
     Uint32 bg=SDL_MapRGB(screen->format,0xff,0xff,0xff);//the color of background
     Uint32 bg1=SDL_MapRGB(screen->format,240,240,240);//the color of bacdground-1
     Uint32 color[7];//the color of box
     color[0]=SDL_MapRGB(screen->format,240,0,0);
     color[1]=SDL_MapRGB(screen->format,0,240,0);
     color[2]=SDL_MapRGB(screen->format,0,0,240);
     color[3]=SDL_MapRGB(screen->format,240,240,0);
     color[4]=SDL_MapRGB(screen->format,0,240,240);
     color[5]=SDL_MapRGB(screen->format,240,0,240);
     color[6]=SDL_MapRGB(screen->format,200,200,0);
     SDL_Rect ss[20][10];//the box of background
     for(i=0;i<20;i++)//set the value to the box of background
     {
      for(j=0;j<10;j++)
      {
       ss[i][j].x=j*20;
       ss[i][j].y=i*20;
       ss[i][j].w=20;
       ss[i][j].h=20;
      }
     }
     srand(time(NULL));
     //printf("Now Loading.......\n");
     //SDL_Delay(1000);
     while(running)
     { 
      if(cycle>0)Cancellation();
      if(move==false)//increase the box
      {
       p=rand()%7;
       if(p==0)Create(O,p);
       if(p==1)Create(I,p);
       if(p==2)Create(J,p);
       if(p==3)Create(L,p);
       if(p==4)Create(S,p);
       if(p==5)Create(Z,p);
       if(p==6)Create(T,p);
       GameOver();
       acount=0;
      }
      //Button();
      if(cycle%8==0)MoveToDown(first);
      if(LR)LeftAndRight();//if left or right was pushed
      if(DN)MoveToDown(first);//if down was pushed
      if(dropping)Drop();//if space was pushed
      //check the condition
      Overlapping();
      Boundary();
      if(correcting)Correct();
      //------------------------
      Overlapping();
      Boundary();
      //increase the box
      if(correcting)Correct();
      //------------------------
      JudgePositionAfterCorrect();
      //Display all box
      SDL_FillRect(screen,&screen->clip_rect,bg1);//background
      for(i=0;i<20;i++)//background
       for(j=0;j<10;j++)
        if(i%2==0&&j%2==1)
         SDL_FillRect(screen,&ss[i][j],bg);
        else if(i%2==1&&j%2==0)
         SDL_FillRect(screen,&ss[i][j],bg);
        else
         SDL_FillRect(screen,&ss[i][j],bg1);
      current=first;//the box
      while(current!=NULL)
      {
       if(current->appearance==0)SDL_FillRect(screen,&current->a,color[0]);
       if(current->appearance==1)SDL_FillRect(screen,&current->a,color[1]);
       if(current->appearance==2)SDL_FillRect(screen,&current->a,color[2]);
       if(current->appearance==3)SDL_FillRect(screen,&current->a,color[3]);
       if(current->appearance==4)SDL_FillRect(screen,&current->a,color[4]);
       if(current->appearance==5)SDL_FillRect(screen,&current->a,color[5]);
       if(current->appearance==6)SDL_FillRect(screen,&current->a,color[6]);
       current=current->next;
      }
      SDL_Flip(screen);
      SDL_Delay(120);//Delay
      cycle++;
      Button();
     }
     SDL_Quit();
    }
    void Button(void)
    {
     SDL_Event event;
     while(SDL_PollEvent(&event))
     {
      switch(event.type)
      {
       case SDL_QUIT:
                      running=false;
                      break;
       case SDL_KEYDOWN:
                      switch(event.key.keysym.sym)
                      {
                         case SDLK_ESCAPE://Quit
                               running=false;
                               break;
         case SDLK_SPACE://Drop
          dropping=true;
          break;
         case SDLK_UP://rotation
          Rotation();
          break;
         case SDLK_DOWN:
          dy=20;
          DN=true;
          break;
         case SDLK_LEFT:
          dx=-20;
          LR=true;
          break;
         case SDLK_RIGHT:
          dx=20;
          LR=true;
          break;
        }
        break;
       case SDL_KEYUP:
        switch(event.key.keysym.sym)
        {
         case SDLK_DOWN:
          dy=speed;
          DN=false;
          break;
         case SDLK_LEFT:
          LR=false;
          break;
         case SDLK_RIGHT:
          LR=false;
          break;
        }
        break;
      }
     }
    }
    void Create(int R[],int c)
    { 
     //printf("-create-%d\n",number);
     int i; 
     for(i=0;i<4;i++)
     {
      current=(BRICK *)malloc(sizeof(BRICK));
      current->a.x=R[i];
      current->a.y=R[i+4];
      current->a.w=20;
      current->a.h=20;
      current->appearance=c;
      if(number==0&&i==0)
      {
       first=current;
       current->next=NULL;
       //previous=current;
      }
      else
      {
       current->next=first;
       first=current;
      }
     }
     number++;
     move=true;
    }
    void Overlapping(void)
    {
     //printf("-Overlapping\n");
     current=first;
     i=0;
     while(i<4)
     {
      temp=first;
      for(j=0;j<4;j++)temp=temp->next;
      while(temp!=NULL)
       {
       if(current->a.y==temp->a.y)
       {
        if(current->a.x==temp->a.x)correcting=true;
       }
       temp=temp->next;
      }
      current=current->next;
      i++;
     }
    }
    void Boundary(void)
    {
     //printf("--BottomAndBoundary\n");
     current=first;
     i=0;
     while(i<4)
     {
      if(current->a.x<0)correcting=true;
      if(current->a.x>200-current->a.w)correcting=true;
      current=current->next;
      i++;
     }
    }
    void Correct(void)
    {
     //printf("Correct\n");
     current=first;
     for(j=0;j<4;j++)
     {
      current->a.x=current->a.x-dx;
      current=current->next;
     }
     correcting=false;
    }
    void GameOver(void)
    {
     //Game over
     current=first;
     i=0;
     while(i<4)
     {
      temp=first;
      for(j=0;j<4;j++)temp=temp->next;
      while(temp!=NULL)
      {
       if(current->a.x==temp->a.x)
       {
        if(current->a.y==temp->a.y)running=false;
       }
       temp=temp->next;
      }
      current=current->next;
      i++;
     }
     if(running==false)printf("Game Over!!\n");
    }
    void JudgePositionAfterCorrect(void)
    {
     current=first;
     i=0;
     while(i<4)
     {
      temp=first;
      for(j=0;j<4;j++)temp=temp->next;
      while(temp!=NULL)
      {
       if(current->a.x==temp->a.x)
       {
        if(current->a.y==temp->a.y-20)move=false;
       }
       temp=temp->next;
      }
      if(current->a.y>=400-current->a.h)
      {
       current->a.y=400-current->a.h;
       move=false;
      }
      current=current->next;
      i++;
     }
    }
    void Rotation(void)
    {
     current=first; 
     J1=current->a.x;
     I1=current->a.y;
     switch(p)//find the center(Cx,Cy) of box
     {
      case 1:
       if(acount==0)
       {
        Cx=((J1+20)+J1)/2;
        Cy=((I1+80)+I1)/2;
       }
       if(acount==1)
       {
        Cx=((J1-60)+(J1+20))/2;
        Cy=((I1+20)+I1)/2;
       }
       if(acount==2)
       {
        Cx=((J1+20)+J1)/2;
        Cy=((I1-60)+(I1+20))/2;
       }
       if(acount==3)
       {
        Cx=((J1+80)+J1)/2;
        Cy=((I1+20)+I1)/2;
       }
       break;
      case 2:
      case 3:
      case 4:
      case 6:
       if(acount==0)
       {
        Cx=((J1+40)+J1)/2;
        Cy=((I1+60)+I1)/2;
       }
       if(acount==1)
       {
        Cx=((J1-40)+(J1+20))/2;
        Cy=((I1+40)+I1)/2;
       }
       if(acount==2)
       {
        Cx=J1;
        Cy=((I1-40)+(I1+20))/2;
       }
       if(acount==3)
       {
        Cx=((J1+60)+J1)/2;
        Cy=I1;
       }
       break;
      case 5:
       if(acount==0)
       {
        Cx=J1;
        Cy=((I1+60)+I1)/2;
       }
       if(acount==1)
       {
        Cx=((J1-40)+(J1+20))/2;
        Cy=I1;
       }
       if(acount==2)
       {
        Cx=((J1+40)+J1)/2;
        Cy=((I1-40)+(I1+20))/2;
       }
       if(acount==3)
       {
        Cx=((J1+60)+J1)/2;
        Cy=((I1+40)+I1)/2;
       }
       break;
     }
     i=0;//(J1,I1)->(J2,I2)
     while(i<4)
     {
      if(p==0)break;
      J1=current->a.x;
      I1=current->a.y;
      //J2=(J1-Cx)*cos(Theta)-(I1-Cy)*sin(Theta)+Cx
      //I2=(J1-Cx)*sin(Theta)+(I1-Cy)*cos(Theta)+Cy
      J2=(0-(I1-Cy)*1)+Cx;
      I2=((J1-Cx)*1)+Cy;
      //------------------------------
      if(acount>=2)current->a.x=J2-30;
      else
       current->a.x=J2-10;
      if(acount%2==0)current->a.y=I2-10;
      else
       current->a.y=I2+10;
      current=current->next;
      i++;
     }
     if(acount==3)acount=0;
     else
      acount++;
    }
    void MoveToDown(BRICK *deliver)
    {
     i=0;
     while(i<4)
     {
      deliver->a.y=deliver->a.y+dy;
      deliver=deliver->next;
      i++;
     }
    }
    void LeftAndRight(void)
    {
     current=first;
     i=0;
     while(i<4)
     {
      current->a.x=current->a.x+dx;
      current=current->next;
      i++;
     }
    }
    void Drop(void)
    {
     while(1)
     {
      MoveToDown(first);
      JudgePositionAfterCorrect();
      if(move==false)break;
     }
     dropping=false;
    }
    void Cancellation(void)
    {
     i=0;
     while(i<=380)
     { 
      current=first;
      for(j=0;j<4;j++)current=current->next;
      while(current!=NULL)
      {
       if(current->a.y==i)ee++;
       current=current->next;
      }
      if(ee==10)
      { 
       current=first;
       //for(j=0;j<4;j++)current=current->next;
       while(current!=NULL)//delete the node
       {
        if(current->a.y!=i)
        {
         temp=current;
         current=current->next;
        }
        else
        {
         temp->next=current->next;
         previous=current;
         current=current->next;
         free(previous);
        }
       }
       current=first;
       //for(j=0;j<4;j++)current=current->next;
       while(current!=NULL)
       {
        if(current->a.y<i)current->a.y=current >a.y+20;
        current=current->next;
       }
      }
      ee=0;
      i=i+20;
     }
    }

    SDL - Step6 貪食蛇



    螢幕截圖:

    #include<stdio.h>
    #include<stdlib.h>
    #include<SDL/SDL.h>
    #include<time.h>
    #include<stdbool.h>
    #define length 800
    #define wide 600
    #define num 5
    struct node
    {
     SDL_Rect snake;
     struct node *next;
    };
    typedef struct node rect; 
    int main(int argc,char** argv)
    {
     SDL_Init(SDL_INIT_EVERYTHING);
     SDL_Surface *screen;
     screen=SDL_SetVideoMode(length,wide,32,SDL_SWSURFACE);
     SDL_WM_SetCaption("((((^.^))))****TaiQing's SDL Snake****((((^.^))))",NULL);
     bool running=true;
     Uint32 start; 
     Uint32 color=SDL_MapRGB(screen->format,0,0,0);
     Uint32 color1=SDL_MapRGB(screen->format,255,0,0);
     Uint32 color2=SDL_MapRGB(screen->format,255,255,255);
     int i,dx=-22,dy=0;
     srand(time(NULL));
     SDL_Rect food;
     food.x=rand()%36*22+4;
     food.y=rand()%27*22+14;
     food.w=20;
     food.h=20;
     rect *first,*current,*previous,*increase; 
     //first第一個節點 current正在處理的節點 previous前一節點指標 increase新節點
    for(i=0;i<num;i++) 
     {
      current=(rect *) malloc(sizeof(rect));
      current->snake.x=(400+22*i);
      current->snake.y=300;
      current->snake.w=20;
      current->snake.h=20;
      if(i==0)
       first=current;
      else
       previous->next=current;
      current->next=NULL;
      previous=current;
     }
     while(running)
     {
      start=SDL_GetTicks();
      SDL_Event event;
      //keyboard  
      while(SDL_PollEvent(&event))
            {
       switch(event.type) 
       {
    case SDL_QUIT:
          running=false;
          break;
         case SDL_KEYDOWN:
          switch(event.key.keysym.sym) 
          {
           case SDLK_ESCAPE:
            running=false;
            break;
           case SDLK_UP:
            if(dx!=0)        
             dy=-22;
            dx=0;         
            break;
           case SDLK_DOWN:
            if(dx!=0)        
             dy=22;
            dx=0;
            break;
           case SDLK_LEFT:
            if(dy!=0)
             dx=-22;
            dy=0;
            break;
           case SDLK_RIGHT:
            if(dy!=0)
             dx=22;
            dy=0;
            break;
          }
          break;     
       }
      }
      //move
      current=first;  
      while(current->next!=NULL)
       current=current->next;
      while(current!=first)
      {
       previous=first; 
       while(previous->next!=current)
        previous=previous->next;
       current->snake.x=previous->snake.x;
       current->snake.y=previous->snake.y;
       current=previous;
      }
      first->snake.x+=dx;
      first->snake.y+=dy;
      //eat food and change length
      if(first->snake.x==food.x && first->snake.y==food.y)
      {
       food.x=rand()%36*22+4;
       food.y=rand()%27*22+14;
       increase=(rect *) malloc(sizeof(rect));
       current=first;  
       while(current->next!=NULL)
        current=current->next;
       if(current->next==NULL)
       {
        increase->snake=current->snake;
        increase->next=NULL;
        current->next=increase;
       }
      }
      //die or dorder
      if(first->snake.x<0 || first->snake.x>780)
       running=false;
      if(first->snake.y<0 || first->snake.y>580)
       running=false;
      current=first;
      current=current->next;
      while(current!=NULL)
      {
       if(current->snake.x==first->snake.x && current->snake.y==first->snake.y)
        running=false;
       current=current->next;
      }
      //render
      SDL_FillRect(screen,&screen->clip_rect,color);
      SDL_FillRect(screen,&food,color2);
      current=first;    
      while(current!=NULL)
      {     
       SDL_FillRect(screen,&(current->snake),color1);
       current=current->next;  
      } 
     SDL_Flip(screen);
     SDL_Delay(100);    
     }
     SDL_Quit();
     return 0;  
    }

    SDL - Step5 打磚塊


    螢幕截圖:

    #include<stdio.h>
    #include<stdlib.h>
    #include<SDL/SDL.h>
    #include<time.h>
    #include<stdbool.h>
    #define m 4
    int main(int argc,char** argv)
    {
       SDL_Init(SDL_INIT_EVERYTHING);
       SDL_Surface *screen;
       screen=SDL_SetVideoMode(300,300,32,SDL_SWSURFACE);
    
       bool running=true;
       int dx=1,dy=-1,R=255,G=255,B=255;
       bool a[2]={0,0};
       bool b[m]={0}; 
       Uint32 start;
       SDL_Rect rect,board,brick[m];
       srand(time(NULL));
    
    /*ball*/
       rect.x=180;
       rect.y=175;
       rect.w=15;
       rect.h=15;
    
    /*board*/
       board.x=110;
       board.y=295;
       board.w=60;
       board.h=5;
    
    /*brick*/
       int i;
       for(i=0;i<m;i++)
     {
        brick[i].x=75*i;
        brick[i].y=40;
        brick[i].w=70;
        brick[i].h=20;      
     }
    
       Uint32 color=SDL_MapRGB(screen->format,0,0,0);
       Uint32 color2;
       Uint32 color3=SDL_MapRGB(screen->format,255,0,0);
       Uint32 color4=SDL_MapRGB(screen->format,0,0,255);   
       
       while(running)
       {  
            start = SDL_GetTicks();
     SDL_Event event;
            Uint32 color2=SDL_MapRGB(screen->format,R,G,B);
            while(SDL_PollEvent(&event))
            {
                 switch(event.type) 
                 {
                        case SDL_QUIT:
                             running=false;
                             break;
                        case SDL_KEYDOWN:
                             switch(event.key.keysym.sym) 
                             {
                                    case SDLK_ESCAPE:
      running=false;
            break;
        case SDLK_LEFT:
                                        a[0]=1;
                                        break;
                                    case SDLK_RIGHT:
                                        a[1]=1;
                                        break;
                             }
                             break;     
                       case SDL_KEYUP:
                            switch(event.key.keysym.sym)
                            {
                                    case SDLK_LEFT:
                                        a[0]=0;
                                        break;
                                    case SDLK_RIGHT:
                                        a[1]=0;
                                        break;                                
                            }
                            break;           
                
                 }                          
            }
            /*red board move*/
            if(a[0])
              board.x-=3;
            if(a[1])
              board.x+=3;
            /*red board move 邊界*/
            if(board.x<=0)
              board.x=0;
            if(board.x>=240)
              board.x=240; 
      
    
    /*變色*/  
    if(rect.x==0 || rect.x==285)
     {  
       R=rand()%256;
       G=rand()%256;
       B=rand()%256;
     }
    
    /*ball移動*/
    rect.x+=dx;
    rect.y+=dy;
    
    /*ball死亡後,復活條件*/
    if(rect.y>=300)
     {
       rect.x=125;
       rect.y=180;
       rect.w=15;
       rect.h=15;
     }
    
    /*上,左,右邊界*/
    if(rect.y<=0)
     dy=-dy;
    if(rect.x<=0)
     dx=-dx;
    if(rect.x>=285)
      dx=-dx;
    
    if(rect.y<=0)
     rect.y=0;
    if(rect.x<=0)
     rect.x=0;
    if(rect.x>=285)
     rect.x=285;
    
    /*brick 消失 and ball 反彈*/
    for(i=0;i<m;i++)
    {
       if(b[i]==0)
       { 
     if(rect.x+15>=brick[i].x && rect.x<=brick[i].x+70)
     {
      if(rect.y+15==40 || rect.y==60)
      {
       dy=-dy;
       b[i]=1;
      }
      
     }
    
     if(rect.y<=brick[i].y+20 && rect.y+15>=brick[i].y)
     {
      if(rect.x+15== brick[i].x || rect.x==brick[i].x+70)
      {
       dy=-dy;
       b[i]=1;
      }
     }
       }
    }
     
      
    /*ball and  board 反彈*/
    if(rect.y==280)
       if(rect.x>=board.x-15 && rect.x<=board.x+60)
          {
     dy=-dy;
     rect.y=280;
          }
    
            /*render*/
             SDL_FillRect(screen,&screen->clip_rect,color);
             SDL_FillRect(screen,&rect,color2);
      SDL_FillRect(screen,&board,color3);
     for(i=0;i<4;i++)
       { 
        if(b[i]==0)   
                 SDL_FillRect(screen,&brick[i],color4);
       }
       
             SDL_Flip(screen);
            SDL_Delay(10);
    
        }
       SDL_Quit();
      return 0;
    }

    SDL - Step4 打乒乓球


    螢幕截圖:
    #include"SDL/SDL.h"
    #include<stdio.h>
    #include<stdlib.h>
    #include<time.h>
    int main(int argc,char** argv)
    {
       SDL_Init(SDL_INIT_EVERYTHING);
       SDL_Surface *screen;
       screen=SDL_SetVideoMode(300,300,32,SDL_SWSURFACE);
    
       bool running=true;
       int dx=1,dy=1,R=255,G=255,B=255;
       bool a[2]={0,0};
       bool b[2]={0,0};
     
       Uint32 start;
       SDL_Rect rect,board1,board2;
       srand(time(NULL));
    
    /*ball*/
       rect.x=145;
       rect.y=145;
       rect.w=20;
       rect.h=20;
    
    /*board1*/
       board1.x=290;
       board1.y=0;
       board1.w=10;
       board1.h=80;
    
    /*board2*/
       board2.x=0;
       board2.y=0;
       board2.w=10;
       board2.h=80;
    
       Uint32 color=SDL_MapRGB(screen->format,0,0,0);
       Uint32 color2;
       Uint32 color3=SDL_MapRGB(screen->format,255,0,0);
       Uint32 color4=SDL_MapRGB(screen->format,0,255,0);   
       
       while(running)
       {  
            start = SDL_GetTicks();
     SDL_Event event;
            Uint32 color2=SDL_MapRGB(screen->format,R,G,B);
            while(SDL_PollEvent(&event))
            {
                 switch(event.type) 
                 {
                        case SDL_QUIT:
                             running=false;
                             break;
                        case SDL_KEYDOWN:
                             switch(event.key.keysym.sym) 
                             {
                                    case SDLK_ESCAPE:
            running=false;
            break;
        case SDLK_UP:
                                        a[0]=1;
                                        break;
                                    case SDLK_DOWN:
                                        a[1]=1;
                                        break;
                                    case SDLK_w:
                                        b[0]=1;
                                        break;
                                    case SDLK_x:
                                        b[1]=1;
                                        break;
                             }
                             break;     
                       case SDL_KEYUP:
                            switch(event.key.keysym.sym)
                            {
                                    case SDLK_UP:
                                        a[0]=0;
                                        break;
                                    case SDLK_DOWN:
                                        a[1]=0;
                                        break;
                                    case SDLK_w:
                                        b[0]=0;
                                        break;
                                    case SDLK_x:
                                        b[1]=0;
                                        break;
                            }
                            break;           
                
                 }                          
            }
    /*red board move*/
            if(a[0])
              board1.y-=10;
            if(a[1])
              board1.y+=10;
            /*red board move 邊界*/
            if(board1.y<=0)
              board1.y=0;
            if(board1.y>=220)
              board1.y=220; 
            /*green board move*/
            if(b[0])
              board2.y-=10;
            if(b[1])
              board2.y+=10;
            /*green board move邊界*/
            if(board2.y<=0)
              board2.y=0;
            if(board2.y>=220)
              board2.y=220;
    
    /*變色*/  
    if(rect.y==0 || rect.y==280)
     {  
       R=rand()%256;
       G=rand()%256;
       B=rand()%256;
     }
    
    rect.x+=dx;
    rect.y+=dy;
    /*ball死亡條件*/
    if(rect.x<0)
     {
       rect.x=145;
       rect.y=145;
       rect.w=20;
       rect.h=20;
     }
    if(rect.x>=300)
     { 
       rect.x=145;
       rect.y=145;
       rect.w=20;
       rect.h=20;
     }
    if(rect.y<=0)
    dy=-dy;
    if(rect.y>=280)
    dy=-dy;
    
    /*上下邊界*/
    if(rect.y<=0)
    rect.y=0;
    if(rect.y>=280)
    rect.y=280;
    
    /*ball and green board 反彈*/
    if(rect.x==10)
       if(rect.y>=board2.y-20 && rect.y<=board2.y+80)
          {
            dx=-dx;
            rect.x=10;
          }
    
    /*ball and red board 反彈*/
    if(rect.x==270)
       if(rect.y>=board1.y-20 && rect.y<=board1.y+80)
          {
            dx=-dx;
            rect.x=270;
          }
            /*render*/
             SDL_FillRect(screen,&screen->clip_rect,color);
             SDL_FillRect(screen,&rect,color2);
      SDL_FillRect(screen,&board1,color3);
             SDL_FillRect(screen,&board2,color4);
             SDL_Flip(screen);
        
            SDL_Delay(10);
    
        }
     SDL_Quit();
     return 0;
    
    }

    SDL - Step3 方塊碰撞邊界會反彈並且變色


    螢幕截圖:
    #include<stdio.h>
    #include<stdlib.h>
    #include<SDL/SDL.h>
    #include<time.h>
    int main(int argc,char** argv)
    {
       SDL_Init(SDL_INIT_EVERYTHING);
       SDL_Surface *screen;
       screen=SDL_SetVideoMode(300,300,32,SDL_SWSURFACE);
       bool running=true;
       int dx=1,dy=1,R=255,G=255,B=255; 
       Uint32 start;
       SDL_Rect rect;
       srand(time(NULL));
       rect.x=145;
       rect.y=145;
       rect.w=20;
       rect.h=20;
       Uint32 color=SDL_MapRGB(screen->format,0,0,0);
       Uint32 color2;
      
       
       while(running)
       {  
            start = SDL_GetTicks();
     SDL_Event event;
            Uint32 color2=SDL_MapRGB(screen->format,R,G,B);
            while(SDL_PollEvent(&event))
            {
    switch(event.type) 
                 {
                        case SDL_QUIT:
                             running=false;
                             break;
                        case SDL_KEYDOWN:
                             switch(event.key.keysym.sym) 
                             {
                                    case SDLK_UP:
                                        dy=-1;
                                        break;
                                    case SDLK_LEFT:
                                        dx=-1;
                                        break;
                                    case SDLK_DOWN:
                                        dy=1;
                                        break;
                                    case SDLK_RIGHT:
                                        dx=1;
                                        break;
    
    
                                    case SDLK_a:
                                         if(dx>=0 && dy>=0)
                                          {  
                                            dx++;
                                            dy++;
                                          } 
                    if(dx>=0 && dy<=0)
                                          { 
                                            dx++;
                                            dy--;
                                          }
                    if(dx<=0 && dy>=0)
                                          { 
                                            dx--;
                                            dy++;
                                          }
                           if(dx<=0 && dy<=0)
                                          { 
                                            dx--;
                                            dy--;
                                          } 
                                        break;
                                    case SDLK_d:
                                          if(dx>=0 && dy>=0)
                                          {
                                            dx--;
                                            dy--;
                                          }
                                         if(dx>=0 && dy<=0)
                                          {
                                            dx--;
                                            dy++;
                                          }
                                         if(dx<=0 && dy>=0)
                                          {
                                            dx++;
                                            dy--;
                                          }
                                         if(dx<=0 && dy<=0)
                                          {
                                            dx++;
                                            dy++;
                                          } 
                                        break;
                              }
                              break;                       
                 }                          
            }
    if(rect.x==0 || rect.x==280 || rect.y==0 || rect.y==280)
     {  
       R=rand()%256;
       G=rand()%256;
       B=rand()%256;
     }
    if(R==0 && G==0 && B==0)
          { 
            R=rand()%256;
            G=rand()%256; 
            B=rand()%256;
          }
    rect.x+=dx;
    rect.y+=dy;
    if(rect.x<=0)
    dx=-dx;
    if(rect.x>=280)
    dx=-dx;
    if(rect.y<=0)
    dy=-dy;
    if(rect.y>=280)
    dy=-dy;
    
    
    if(rect.x<=0)
    rect.x=0;
    if(rect.x>=280)
    rect.x=280;
    if(rect.y<=0)
    rect.y=0;
    if(rect.y>=280)
    rect.y=280;
    
        //render
        SDL_FillRect(screen,&screen->clip_rect,color);
        SDL_FillRect(screen,&rect,color2);
        SDL_Flip(screen);
        
        SDL_Delay(10);
    
        }
     SDL_Quit();
     return 0;
    
    }

    SDL- Step2 鍵盤按鍵控制方塊的移動


    #include<stdlib.h>
    #include<SDL/SDL.h>
    int main(int argc,char** argv)
    {
       SDL_Init(SDL_INIT_EVERYTHING);
       SDL_Surface *screen;
       screen=SDL_SetVideoMode(300,300,32,SDL_SWSURFACE);
       bool running=true;
    
       Uint32 start;
       bool b[4]={0,0,0,0};
       SDL_Rect rect;
       rect.x=145;
       rect.y=145;
       rect.w=10;
       rect.h=10;
       Uint32 color=SDL_MapRGB(screen->format,0,0,0);
       Uint32 color2=SDL_MapRGB(screen->format,0xff,0xff,0xff);
       while(running)
       {
            start = SDL_GetTicks();
            SDL_Event event;
            while(SDL_PollEvent(&event))
            {
    switch(event.type)
                 {
                        case SDL_QUIT:
                             running=false;
                             break;
                        case SDL_KEYDOWN:
                             switch(event.key.keysym.sym)
                             {
                                    case SDLK_UP:
                                        b[0]=1;
                                        break;
                                    case SDLK_LEFT:
                                        b[1]=1;
                                        break;
                                    case SDLK_DOWN:
                                        b[2]=1;
                                        break;
                                    case SDLK_RIGHT:
                                        b[3]=1;
                                        break;
    
                              }
                              break;
                         case SDL_KEYUP:
                              switch(event.key.keysym.sym)
                              {
                                     case SDLK_UP:
                                         b[0]=0;
                                         break;
                                     case SDLK_LEFT:
                                         b[1]=0;
                                         break;
                                     case SDLK_DOWN:
                                         b[2]=0;
                                         break;
                                     case SDLK_RIGHT:
                                         b[3]=0;
                                         break;
                              }
                              break;
                 }
    
            }
            //logic
            if(b[0])
              rect.y-=10;
            if(b[1])
              rect.x-=10;
            if(b[2])
              rect.y+=10;
            if(b[3])
              rect.x+=10;
    
    
            if( rect.y<0)
                    rect.y=0;
            if(rect.y>290)
                    rect.y=290;
            if(rect.x<0)
                    rect.x=0;
            if(rect.x>290)
                    rect.x=290;
            //render
             SDL_FillRect(screen,&screen->clip_rect,color);
             SDL_FillRect(screen,&rect,color2);
             SDL_Flip(screen);
       SDL_Delay(50);
       }
     SDL_Quit();
     return 0;
    
    }

    編譯指令 : g++ XXX.c -o LLL -lSDL