資訊社放學社課-網頁

講師:王政凱

Finish

講師介紹

  • 227王政凱
  • ck_platypus
  • 建中資訊 學術兼外交
  • HTML, JS是我母語欸
  • 我不會資訊
  • FB:王政凱
  • IG:@kennywang2017

Finish

網頁初探

Finish

What is 網頁 ?

網際網路

全球資訊網

網域

網站

網址

網址

網址

網頁

網頁

網頁

Finish

網頁設計 vs 網站開發

網頁設計:

前端,與使用者直接連結的頁面

畫面構圖以及單個網頁的使用者互動

網站開發:

後端,將數個網頁統整處理資料

不同網頁間相互連結及資料的傳遞

Finish

網頁組成

HTML

[架構]

CSS

[外觀]

Java Script

[互動]

Finish

網頁範例

Finish

HTML簡介

Finish

What is HTML ?

Hyper Text Markup Language

一種程式語言

可被網頁瀏覽器讀取並成像

建構文字、圖像、物件

可結合css, java script

Finish

HTML網頁

<!DOCTYPE html>
<html>
  <head>
    <title>Page title</title>
  </head>
  <body>
    <p>This is a paragraph.</p>
  </body>
</html>

這是一個最基本的html網頁

Finish

HTML網頁

可以這樣理解

宣告一個html檔案

整個html網頁

網頁的頁首及基本資訊

網頁的主體(能看到的東西)

Finish

My first HTML

<!DOCTYPE html>
<html>
  <head>
    <title>My first HTML</title>
  </head>
  <body>
    <p>Hello world</p>
  </body>
</html>

複製這段到記事本再強制轉檔成.html

Finish

My first HTML

想要更方便(看起來比較漂亮)

可以下載Visual Studio Code

有一些快速鍵可以用

可以調程式碼的顏色

Finish

可能會發現

Finish

東西都被<>包起來欸

Finish

好酷喔

Finish

HTML 元素

有些元素不需要結束標籤

Finish

HTML 元素

開始標籤後可以接屬性

Finish

HTML 元素

網頁就是由這一包一包的元素組成起來的

Finish

HTML通用屬性

Finish

HTML通用屬性

HTML元素有很多不同的屬性

有些屬性僅針對單一元素

這邊先介紹所有元素皆通用的屬性

Finish

Class 類別

幫html元素分類

一個元素可以存在多個類別(用空白隔開

<p class="grass poison">妙蛙種子</p>
<p class="fire">小火龍</p>
<p class="fire flying">火焰鳥</p>

Finish

Id 身份

幫html元素編單一身份驗證

每個id只對應到一個元素

<p id="#001">妙蛙種子</p>
<p id="#004">小火龍</p>
<p id="#146">火焰鳥</p>

Finish

Style 樣式

樣式是一個很大的主題啊

之後講css的時候會再提到

基本上就是把css的東西搬到元素屬性而已

HTML的顏色

<p style="color:#ff0000;">紅字</p>
<p style="font-size:300%;">大字</p>
<p style="text-align:center;">置中</p>

Finish

先來一點點CSS

Finish

為什麼要 CSS

每個元素都要style好像很麻煩

我想要讓整個網頁的字都變紅色怎麼辦?

可不可以對多個元素設定同樣的樣式?

<p style="color:red;">1.紅</p>
<p style="color:red;">2.洪</p>
<p style="color:red;">3.宏</p>
<p style="color:red;">4.鴻</p>
<p style="color:red;">5.弘</p>

Finish

CSS

對html元素定義統一的樣式

一樣的東西寫一次就好

讓你的html就真的只有架構

程式碼變乾淨~耶

<style>p{color: red;}</style>
<p>1.紅</p>
<p>2.洪</p>
<p>3.宏</p>
<p>4.鴻</p>
<p>5.弘</p>

Finish

元素 CSS

<style>
  p{
    color: #ff0000;
  }
  h1{
    color: #0000ff;
  }
</style>
<p>宏</p>
<p>洪</p>
<h1>嵐</h1>
<h1>蘭</h1>

Finish

類別 CSS

<style>
  .big{
    font-size: 48px;
  }
  .small{
    font-size: 24px;
  }
</style>
<p class="big">巨</p>
<p class="big">豪</p>
<p class="small">細</p>
<p class="small">毫</p>

Finish

身份 CSS

<style>
  #sky{
    border: 10px solid DarkBlue;
  }
  #sun{
    border: 10px solid AliceBlue;
  }
  #blood{
    border: 10px solid Crimson;
  }
</style>
<p id="sky">青天</p>
<p id="sun">白日</p>
<p id="blood">滿地紅</p>

Finish

HTML元素(文字

Finish

Title 標題

<head>
  <title>這會顯示在瀏覽器上面那條</title>
</head>

<title>元素只能放在<head>底下

就是瀏覽器上面那條

也可以算是網頁名稱吧

好像沒有特殊的屬性

Finish

Paragraph 段落

<p>我是一個段落</p>
<p>我被切<br>成兩半</p>
<p>我被線分<hr>成兩半</p>

接下來介紹的東西都是放在<body>底下

<p>就是文字段落常跟<br>, <hr>一起用

<br>不需結束標籤,表換行

<hr>亦不需結束標籤,表分隔線

Finish

Heading 段落標題

<h1>我超大</h1>
<h2>我次大</h2>
<h6>我超小</h6>

<h1>~<h6>從大到小

就段落的標題

就這樣

Finish

一群酷字

<b>粗粗</b>
<strong>另一個粗粗</strong>
<i>斜斜</i>
<em>另一個斜斜</em>
<mark>黃黃</mark>
<small>小小</small>
<del>割割</del>
<ins>底底</ins>
<sub>下下</sub>
<sup>上上</sup>

粗粗 另一個粗粗 斜斜 另一個斜斜 黃黃 小小 割割 底底 下下 上上

Finish

list 清單

<ol>
  <li>aaa</li>
  <li>bbb</li>
</ol>
<ul>
  <li>ccc</li>
  <li>ddd</li>
</ul>

ordered list, unordered list

自己寫寫看就知道是什麼東西了

Finish

lists

點點可以改圖案

數字可以改標示方法

ul {
  list-style-type: square;
}
ol {
  list-style-type: upper-roman;
}

Finish

Emoji 表情符號

<p>&#128539;</p>
<p>&#129430;</p>
<p>&#129412;</p>
<p>&#127757;</p>
<p>&#127758;</p>

Finish

HTML元素(圖片

Finish

Link-icon 圖標?

<head>
  <link rel="icon" href="URL"> 
</head>

link元素可以把檔案從其他地方引入html

存在很多不同的功能的rel屬性

我只有要介紹rel="icon"(其他的之後講

href屬性後面要放網址但這邊塞不下

一樣只能放在<head>底下

就是瀏覽器上面那張圖片

Finish

Image 圖片

<img src="01.png" alt="img">
<img src="01.gif" alt="img">
<img src="URL" alt="img">

img元素只有開始標籤沒有結束標籤

src屬性後面可以放網址或同個資料夾內的檔案

alt為替代文字,圖片無法顯示時替代

Finish

Image 圖片

<style>
  img{
    float: right;
    width: 100px;
    height: 80px;
  }
</style>
<img src="01.png" alt="img">

float是與文字對齊效果(文繞圖?

width, height可以調圖片大小(px, %)

Finish

map 圖

<img src="01.png" usemap="#map01">
<map name="map01">
  <area shape="rect" coords="x1,y1,x2,y2" href="URL">
  <area shape="circle" coords="x,y,r" href="URL">
  <area shape="poly" coords="x,y,......" onclick="f()">
</map>

map可以看作是image的附件

可以給圖片中的某區塊連結(或JS函式

有rect(矩形), circle(圓形), poly(多邊形)

Finish

HTML元素(排版

Finish

Table 表格-basic

<table>
  <tr>
    <th>apple</th>
    <th>banana</th>
  </tr>
  <tr>
    <td>coconut</td>
    <td>durian</td>
  </tr>
</table>
apple banana
coconut durian

table header

table row

table data

Finish

Table 表格-size

<table>
  <tr>
    <th style="width: 500px;">apple</th>
    <th>banana</th>
  </tr>
  <tr>
    <td>coconut</td>
    <td style="height: 500px;">durian</td>
  </tr>
</table>

Finish

Table 表格-border

td {
  border: 5px solid black;
  border-radius: 10px;
  background-color: aqua;
  border-style: dotted dashed solid double;
}
table {
  border: 5px solid greenyellow;
  border-style: groove ridge inset outset;
  border-spacing: 20px;
}

Finish

Table 表格-merge

<table>
  <tr>
    <td colspan="2">apple</td>
    <td rowspan="2">banana</td>
  </tr>
  <tr>
    <td>coconut</td>
    <td>durian</td>
  </tr>
</table>

Finish

Table 表格-複習一下

td:hover {
  background-color: blueviolet;
}
td:active {
  font-size: 200%;
}

Finish

Division 區塊?

<div>
  <h1>我是一個區塊</h1>
  <p>區塊裡可以放很多元素</p>
  <img src="不一定要是文字.jpg">
</div>

把網頁切成一塊一塊的物件

對排版很有用(分區治理

大型網頁非常需要

Finish

Division 區塊?

<style>
  #big{
    display: flex;
    justify-content: center;
    justify-content: space-between;
    justify-content: space-around;
  }
</style>
<div id="big">
  <div>1</div>
  <div>2</div>
</div>

Finish

Span 行內區塊?

<style>
  span {
    border: 2px double orange;
    color: #af5fbf;
  }
</style>
<p>dsaofiie<span>0123</span>fadskaf</p>

對,就是行內的區塊

Finish

HTML元素(互動

Finish

Links 連結

<a href="URL">酷</a>
<a href="URL" target="_self">酷</a>
<a href="URL" target="_blank">酷</a>

href屬性後面要放網址但這邊塞不下

target是一個屬性

_self 就是正常打開

_blank 在新分頁中開啟連結

Finish

Links 連結

<a href="#p2">酷</a>
<p id="p1">paragraph1</p>
<p id="p2">paragraph1</p>

href後面也可以不放網址

可以放同個網頁內其他元素的id

就可以在網頁中實施連結

Finish

links

可以對連結的不同狀態改樣式

超酷爆

cursor那邊還有很多東西可以放

有興趣的可以看這邊

a:link { color: red;}
a:visited { text-decoration: underline;}
a:hover { cursor: help;}
a:active { font-family:monospace;}

Finish

Input 輸入框

<input type="button">
<input type="checkbox">
<input type="color">
<input type="date">
<input type="month">
<input type="number">
<input type="password">
<input type="radio">
<input type="range">

可以結合之後會教的javascript做使用

Finish

Button 按鈕

<button type="button">a</button>
<button type="reset">b</button>
<button type="submit">c</button>

可以結合之後會教的javascript做使用

Finish

CSS基礎

Finish

CSS語法

就這樣。

之前好像講過

Finish

CSS選擇器

選element

選class

選id

選element中的class

選多個東西

p {color: red;}
.q {color: red;}
#r {color: red;}
p.s {color: red;}
p, .q, #r {color: red;}

Finish

CSS樣式_01

Finish

color

文字顏色

div {
  color: red;
}

Finish

border

邊界

div {
  border-style: dotted;
  border-width: 5px;
  border-color: red;
  border-radius: 5px;
}

Finish

background-color

元素背景顏色 我從這邊學的

div {
  background-color: red;
  background: 
    linear-gradient(yellow 20%, red 80%);
  background: 
    linear-gradient(to bottom right, yellow, red);
  background: 
    radial-gradient(ellipse, white, orange);
  background: 
    radial-gradient(circle at 35% 25%, #fff 0, #000 90%);
  background: 
    repeating-linear-gradient(yellow 5%, red 20%);
}

Finish

background-image

元素背景圖片

div {
  background-image: url('img.jpg');
}

Finish

background-image

很多種背景圖片的排法

div {
  background-image: url('img.jpg');
  background-repeat: repeat-x;
  background-repeat: no-repeat;
  background-position: right top;
  background-attachment: fixed;
  background-attachment: scroll;
}

Finish

Javascript

Finish

寫法

<script>
  
	寫在這裡喔~~~~
    
</script>
<我是其他html元素></我是其他html元素>

Finish

Output

幹也太多種了吧

其實還有更多用法

可以結合其他html元素作使用

document.getElementById("id").innerHTML="輸出";
document.write("書初");
alert("loseout")
console.log("gj tj ")
print(1+2+3)

Finish

Variables

好像跟其他程式語言蠻像的

var a=7122
var b="jizz"
var c='jizz'

Finish

Operators

好像跟其他程式語言蠻像的

var a=7122
var b=87
alert(a+b)
console.log(a*b)
var c="aaa"
var d="bbb"
alert(c+d)

Finish

Operators

其實否

var a="5"
var b=5
alert(a+b)
alert(a*b)
var c=5+5+"5"
alert(c)
c=5
alert(c+5)

Finish

Array

陣列即數列

var a=[]
a[0]=1
a[1]=2
a[2]=[]
a[2][0]=3
a[2][1]=4

Finish

Object

超酷欸

真的很酷啦

var Jason={
  age: 16,
  weight: 75,
  height: 183,
  length: 3
}

Finish

Function

函式函式韓式炸雞

function sum(a, b){
  return a+b;
}
function product(a, b){
  return a*b;
}

Finish

Javascript (2)

Finish

迴圈

var i=0;
var s="";
while(i<10){
  s+=" "+i;
  i++;
}

這是while迴圈

Finish

迴圈

var s="";
for(var i=0;i<10;i++){
  s+=" "+i;
}

這是for迴圈

Finish

條件判斷

if(條件式){
  執行這邊
}else{
  條件不成立就執行這邊
}

這是條件判斷

Finish

一個重複執行的迴圈

var cnt=0;
setInterval(function(){
  cnt++;
  document.getElemeniById("a").innerHTML=cnt;
}, 1000);

這是setInterval迴圈

Finish

對HTML元素做事

document.getElementById("paragraph1").innerHTML="喔酷欸";
var a=document.getElementById("button1");
var b=document.getElementById("input1");
a.onclick=function(){
  console.log("按鈕已按下");
  alert(b.value);
}

還有很多其他事情可以做

Finish

Math

Math.floor()
Math.sin()
Math.random()
Math.log()
Math.pow()
......

Finish

CSS, Javascript匯入

Finish

關於程式碼

雖然我們前面教的都是

把CSS, JavaScript 塞在HTML裡寫

但事實上

大部分的網頁都不是這樣寫成的

我們可以把css跟javascript拆成自己一份文件

Finish

多份文件整合

<!DOCTYPE html>
<html>
  <head>
    
    
  </head>
  <body>
    <h1>
      dcba
    </h1>
    <p>
      abcd
    </p>
  </body>
</html>

Main.html

Style.css

h1 {
  color: blue;
}
p {
  color: red;
  font-size: 20px;
}

Script.js

var a=0;
var i=0;
for(;i<10;i++){
  a+=i*i*i;
}
alert(a);
console.log(a-i);

匯入"Style.css"

匯入"Script.js"

Finish

語法的部分

<head>
  <link rel="stylesheet" href="Style.css">
  <link rel="stylesheet" href="URL">
  <script src="Script.js"></script>
</head>

要注意檔案必須都在同個資料夾底下

如果不是的話還要用奇怪語法去找電腦中的檔案

但是我不會

Finish

Canvas

因為講師不會寫python才學的東西

Finish

Finish

什麼是Canvas

Canvas是一個html元素

它的功能就是一個好用的畫布

可以用Javascript程式以直角坐標系畫出圖形

因為只有用到Javascript,改變十分方便

也可以拿來做動畫、遊戲之類的

Finish

XMLHttpRequest

+Google App Script

Finish

例如

  • 輸入帳密,判斷是否正確
  • 填問卷、報名表
  • 不勝枚舉

Finish

我們想要...

不單純只是在前端做事,需要傳資料給後端資料庫...

這時,XMLHttpRequest就是一個很方便的方式!

Finish

Google App Script

可以當作線上的簡單資料庫,前面的XHR可以呼叫他,然後在這邊寫一些程式對資料庫(e.g. Google Sheet)進行操作

Finish

XHR

//put this in your script
var url = "";
var xhr = new XMLHttpRequest();
xhr.open("POST",url);
var data = new FormData();
xhr.onreadystatechange = function(){
    if(xhr.readyState==4){
      //do something after send
    }
}
xhr.send(data);

Finish

Google App Script端

var file=SpreadsheetApp.openByUrl("your sheet's url");

function doPost(e){
  sheet=file.getSheetByName("sheet's name");
  sheet.getRange("A1:A1").setValues([[e.parameter["str"]]]);
  return ContentService.createTextOutput("123");
}

Finish

一些Document

Finish

實作 #1

我們來做迷宮吧

迷宮怎麼做

簡單來說:

建一個二維陣列儲存每個格子是否被走過

還要順道紀錄每條連接格子的牆壁是否打通

重複打通牆壁在格子中走來走去

有得走就走,沒得走就返回

最終就能製造出隨機的迷宮

也太簡單了吧

然後我們就可以使用 canvas

把每一瞬間的迷宮狀況

都圖像化的用顏色輸出出來

這樣就可以隨時觀察迷宮運作情形

寫迷宮程式時也可以幫助除錯

具體實作

實作之前 #0

把 canvas 的繪圖工具引入

<body>
    <canvas id="myCanvas" width="1400" height="700"></canvas>
    <script>
        var canvas = document.getElementById('myCanvas');
        var cv = canvas.getContext('2d');
      
        var size = 25;//格子大小
        var mapx = 1400/size;
        var mapy = 700/size;
    </script>
</body>

實作之始 #1

來建個二維陣列儲存格子狀態吧

包含格子是否走過(我用顏色存

格子四周的邊是否還存在

格子大小和畫布大小可以隨意設定

var arr = [];
for(var i=0;i<mapx;i++){
    arr[i] = [];
    for(var j=0;j<mapy;j++){
        arr[i][j] = [];
        arr[i][j][0] = "#e0e0e0";
        for(var k=1;k<5;k++){
            arr[i][j][k] = 1;
        }
    }
}

實作之初 #2

為了方便畫畫

我寫了兩個函式來將 canvas 繪圖制式化

function drawrect(x,y,color){
  cv.beginPath();
  cv.rect(x*size+1, y*size+1, size-2, size-2);
  cv.fillStyle = color;
  cv.fill();
}
function drawline(x,y,direction,color){
  cv.beginPath();
  cv.lineWidth = 2;
  if(direction==1){cv.moveTo(x*size, y*size);
                   cv.lineTo((x+1)*size, y*size);}
  if(direction==2){cv.moveTo((x+1)*size, y*size);
                   cv.lineTo((x+1)*size, (y+1)*size);}
  if(direction==3){cv.moveTo((x+1)*size, (y+1)*size);
                   cv.lineTo(x*size, (y+1)*size);}
  if(direction==4){cv.moveTo(x*size, (y+1)*size);
                   cv.lineTo(x*size, y*size);}
  cv.strokeStyle = color;
  cv.stroke();
}

實作精髓 #3

要怎麼創造迷宮?

我們先創造一個針頭象徵目前生成最新的格子

並讓格子擁有三種狀態:沒走過、走過一次、走過多次

如果針頭四周的格子內有沒走過的格子就隨機挑一個走

否則往回走(走針頭附近只走過一次且中間無牆阻擋的

照這樣的策略就能生出一個完整的迷宮了

這邊讓大家花點時間理解一下

範例

實作精髓 #3

setInterval(function() {
  var WallBreak = [];
  if (nowy > 0 && arr[nowx][nowy-1][0] == "#e0e0e0") {WallBreak.push(1);}
  if (nowx < mapx-1 && arr[nowx+1][nowy][0] == "#e0e0e0") {WallBreak.push(2);}
  if (nowy < mapy-1 && arr[nowx][nowy+1][0] == "#e0e0e0") {WallBreak.push(3);}
  if (nowx > 0 && arr[nowx-1][nowy][0] == "#e0e0e0") {WallBreak.push(4);}
  if(WallBreak.length>0){
    arr[nowx][nowy][0] = "#0000ff";
    drawrect(nowx,nowy,arr[nowx][nowy][0]);
    var rand = Math.floor(Math.random()*WallBreak.length);
    arr[nowx][nowy][WallBreak[rand]]=0;
    drawline(nowx,nowy,WallBreak[rand],"#0000ff");
    if(WallBreak[rand]==1){nowy--;}
    if(WallBreak[rand]==2){nowx++;}
    if(WallBreak[rand]==3){nowy++;}
    if(WallBreak[rand]==4){nowx--;}
    arr[nowx][nowy][(WallBreak[rand]+1)%4+1]=0;
  }else{
    arr[nowx][nowy][0] = "#ffff00";
    drawrect(nowx,nowy,"#ffff00");
    if(nowy>0 && arr[nowx][nowy][1]==0 && arr[nowx][nowy-1][0]=="#0000ff"){drawline(nowx,nowy,1,"#ffff00");nowy--;}else
      if(nowx<mapx-1 && arr[nowx][nowy][2]==0 && arr[nowx+1][nowy][0]=="#0000ff"){drawline(nowx,nowy,2,"#ffff00");nowx++;}else
        if(nowy<mapy-1 && arr[nowx][nowy][3]==0 && arr[nowx][nowy+1][0]=="#0000ff"){drawline(nowx,nowy,3,"#ffff00");nowy++;}else
          if(nowx>0 && arr[nowx][nowy][4]==0 && arr[nowx-1][nowy][0]=="#0000ff"){drawline(nowx,nowy,4,"#ffff00");nowx--;}
  }
  drawrect(nowx,nowy,"#ff0000");
}, 1);

實作之末 #4

最後我會把所有格子重新上色

牆壁也重新上色

似乎比較美觀?

if(nowx!=0 || nowy!=0 || arr[mapx-1][mapy-1][0]!="#ffff00"){
  //實作精髓 #3
}else{
  cv.fillStyle = "#409070";
  cv.fillRect(0, 0, canvas.width, canvas.height);
  for(var i=0;i<mapx;i++){
    for(var j=0;j<mapy;j++){
      for(var k=1;k<5;k++){
        if(arr[i][j][k]){drawline(i,j,k,"#ff0000");}
      }
    }
  }
}

整份扣的

大家把這份複製到自己的檔案應該就可以跑了

但還是推薦大家自己寫一次或是認真搞懂每行程式碼啦

<!DOCTYPE HTML>
<html>

<head>
</head>

<body>
    <canvas id="myCanvas" width="1400" height="700"></canvas>
    <script>
        var canvas = document.getElementById('myCanvas');
        var cv = canvas.getContext('2d');

        var size = 25;
        var mapx = 1400/size;
        var mapy = 700/size;

        var nowx=0,nowy=0;
        var arr = [];
        for(var i=0;i<mapx;i++){
            arr[i] = [];
            for(var j=0;j<mapy;j++){
                arr[i][j] = [];
                arr[i][j][0] = "#e0e0e0";
                drawrect(i,j,arr[i][j][0]);
                for(var k=1;k<5;k++){
                    arr[i][j][k] = 1;
                    drawline(i,j,k,"#000000");
                }
            }
        }

        function drawrect(x,y,color){
            cv.beginPath();
            cv.rect(x*size+1, y*size+1, size-2, size-2);
            cv.fillStyle = color;
            cv.fill();
        }
        function drawline(x,y,direction,color){
            cv.beginPath();
            cv.lineWidth = 2;
            if(direction==1){cv.moveTo(x*size, y*size);
                cv.lineTo((x+1)*size, y*size);}
            if(direction==2){cv.moveTo((x+1)*size, y*size);
                cv.lineTo((x+1)*size, (y+1)*size);}
            if(direction==3){cv.moveTo((x+1)*size, (y+1)*size);
                cv.lineTo(x*size, (y+1)*size);}
            if(direction==4){cv.moveTo(x*size, (y+1)*size);
                cv.lineTo(x*size, y*size);}
            cv.strokeStyle = color;
            cv.stroke();
        }

        setInterval(function() {
            if(nowx!=0 || nowy!=0 || arr[mapx-1][mapy-1][0]!="#ffff00"){
                var WallBreak = [];
                if (nowy > 0 && arr[nowx][nowy-1][0] == "#e0e0e0") {WallBreak.push(1);}
                if (nowx < mapx-1 && arr[nowx+1][nowy][0] == "#e0e0e0") {WallBreak.push(2);}
                if (nowy < mapy-1 && arr[nowx][nowy+1][0] == "#e0e0e0") {WallBreak.push(3);}
                if (nowx > 0 && arr[nowx-1][nowy][0] == "#e0e0e0") {WallBreak.push(4);}
                if(WallBreak.length>0){
                    arr[nowx][nowy][0] = "#0000ff";
                    drawrect(nowx,nowy,arr[nowx][nowy][0]);
                    var rand = Math.floor(Math.random()*WallBreak.length);
                    arr[nowx][nowy][WallBreak[rand]]=0;
                    drawline(nowx,nowy,WallBreak[rand],"#0000ff");
                    if(WallBreak[rand]==1){nowy--;}
                    if(WallBreak[rand]==2){nowx++;}
                    if(WallBreak[rand]==3){nowy++;}
                    if(WallBreak[rand]==4){nowx--;}
                    arr[nowx][nowy][(WallBreak[rand]+1)%4+1]=0;
                }else{
                    arr[nowx][nowy][0] = "#ffff00";
                    drawrect(nowx,nowy,"#ffff00");
                    if(nowy>0 && arr[nowx][nowy][1]==0 && arr[nowx][nowy-1][0]=="#0000ff"){drawline(nowx,nowy,1,"#ffff00");nowy--;}else
                    if(nowx<mapx-1 && arr[nowx][nowy][2]==0 && arr[nowx+1][nowy][0]=="#0000ff"){drawline(nowx,nowy,2,"#ffff00");nowx++;}else
                    if(nowy<mapy-1 && arr[nowx][nowy][3]==0 && arr[nowx][nowy+1][0]=="#0000ff"){drawline(nowx,nowy,3,"#ffff00");nowy++;}else
                    if(nowx>0 && arr[nowx][nowy][4]==0 && arr[nowx-1][nowy][0]=="#0000ff"){drawline(nowx,nowy,4,"#ffff00");nowx--;}
                }
                drawrect(nowx,nowy,"#ff0000");
            }else{
                cv.fillStyle = "#409070";
                cv.fillRect(0, 0, canvas.width, canvas.height);
                for(var i=0;i<mapx;i++){
                    for(var j=0;j<mapy;j++){
                        for(var k=1;k<5;k++){
                            if(arr[i][j][k]){drawline(i,j,k,"#ff0000");}
                        }
                    }
                }
            }
        }, 1);
    </script>
</body>

</html>

實作 #2

我們來做俄羅斯方塊吧

俄羅斯方塊怎麼做

簡單來說:

一樣要建立一個二維陣列的版面

每個格子儲存以下狀態:

正在掉落、空格、已經存在的方塊(顏色

然後另外判斷如果整行都填滿要消行

最困難的部分是旋轉(真的超難

只要一(大)些(量)函式

好像有點難

所以我直接把扣的放出來

<!DOCTYPE HTML>
<html>
<head>
</head>
<body data-rsssl=1>
    <canvas id="myCanvas" width="800" height="640"></canvas>
    <form>
        <button type="submit" id="start" class="">開始遊戲</button>
    </form>
    <script>
        var canvas = document.getElementById('myCanvas');
        var ctx = canvas.getContext('2d');

        ctx.fillStyle = "#303070";
        ctx.fillRect(0, 0, 800, 640);
        for(var i=0;i<1000;i++){
            drawcircle(Math.floor(Math.random()*800),Math.floor(Math.random()*640),Math.floor(Math.random()*2)+1,"#ffffff")
        }
        var arr=[];
        for(var i=0;i<10;i++){
            arr[i]=[];
            for(var j=0;j<20;j++){
                arr[i][j]="#c0c0c0";
            }
        }
        var current_block=[];
        var current_block_type=0;
        var current_spin_center=[];
        var current_color;
        var rotate_state_type=0;
        var already_rotate;
        var hold_block_type=-1;
        var hold_color;
        var already_hold=0;
        var bag=[];
        var next_block_bag=[];
        var block_cnt=0;
        var level;
        var score;
        var line;
        var back_to_back=0;
        initial();
        //drop
        setInterval(function(){
            var can_drop=1;
            for(var i=0;i<4;i++)
                if(arr[current_block[i][0]][current_block[i][1]+1]!="#c0c0c0")
                    can_drop=0;
            if(can_drop){
                current_spin_center[1]++;
                for(var i=0;i<4;i++)
                    current_block[i][1]++;
            }else{
                for(var i=0;i<4;i++)
                    arr[current_block[i][0]][current_block[i][1]]=current_color;
                cleanline();
                newblock();
            }
            blockupdate();
        },gamespeed)
        //keyboard
        document.addEventListener('keydown', function(event) {
            //space : drop to the bottom
            if(event.keyCode == 32) {
                var can_drop=1;
                var drop_count=0;
                for(var i=0;i<4;i++)
                    if(arr[current_block[i][0]][current_block[i][1]+1]!="#c0c0c0")
                        can_drop=0;
                while(can_drop==1){
                    drop_count++;
                    for(var i=0;i<4;i++)
                        current_block[i][1]++;
                    for(var i=0;i<4;i++)
                        if(arr[current_block[i][0]][current_block[i][1]+1]!="#c0c0c0")
                            can_drop=0;
                }
                for(var i=0;i<4;i++)
                    arr[current_block[i][0]][current_block[i][1]]=current_color;
                cleanline();
                newblock();
                blockupdate();
                score+=2*level*drop_count;
                scoreupdate();
            }
            //arrowleft : move left
            if(event.keyCode == 37) {
                var can_move=1;
                for(var i=0;i<4;i++)
                    if(arr[current_block[i][0]-1][current_block[i][1]]!="#c0c0c0")
                        can_move=0;
                if(can_move){
                    current_spin_center[0]--;
                    for(var i=0;i<4;i++)
                        current_block[i][0]--;
                }
                blockupdate();
            }
            //arrowright : move right
            if(event.keyCode == 39) {
                var can_move=1;
                for(var i=0;i<4;i++)
                    if(arr[current_block[i][0]+1][current_block[i][1]]!="#c0c0c0")
                        can_move=0;
                if(can_move){
                    current_spin_center[0]++;
                    for(var i=0;i<4;i++)
                        current_block[i][0]++;
                }
                blockupdate();
            }
            //arrowdown : move down
            if(event.keyCode == 40) {
                var can_drop=1;
                for(var i=0;i<4;i++)
                    if(arr[current_block[i][0]][current_block[i][1]+1]!="#c0c0c0")
                        can_drop=0;
                if(can_drop){
                    current_spin_center[1]++;
                    for(var i=0;i<4;i++)
                        current_block[i][1]++;
                    score+=1*level;
                    scoreupdate();
                }
                blockupdate();
            }
            //arrowup : right rotate
            if(event.keyCode == 38) {
                rotate(1);
                blockupdate();
            }
            //keyc : hold
            if(event.keyCode == 67) {
                hold();
            }
            //keyx : new game
            if(event.keyCode == 88) {
                initial();
            }
            //keyz : left rotate
            if(event.keyCode == 90) {
                rotate(3);
                blockupdate();
            }
        });
        //gamestart
        function initial(){
            for(var i=0;i<10;i++){
                for(var j=0;j<20;j++){
                    arr[i][j]="#c0c0c0";
                }
            }
            block_cnt=5;
            randomblock();
            for(var i=0;i<5;i++) next_block_bag[i]=bag[i];
            newblock();
            clock=0;
            gamespeed=1000;
            level=1;
            score=0;
            line=0;
            scoreupdate()
            for(var i=-7;i<-1;i++){
                for(var j=1;j<7;j++){
                    drawrect(i,j,"#c0c0c0",5,"#a0a0a0",0);
                }
            }
            hold_block_type=-1;
            already_hold=0;
        }
        //generate block
        function randomblock(){
            bag=[0,1,2,3,4,5,6,Math.floor(Math.random()*7)];
            var a,b;
            var temp;
            for(var i=0;i<100;i++){
                a=Math.floor(Math.random()*8);
                b=Math.floor(Math.random()*8);
                temp=bag[a];
                bag[a]=bag[b];
                bag[b]=temp;
            }
        }
        function newblock(){
            current_block_type=next_block_bag[0];
            if(current_block_type == 0){
                current_color = "#ff0000"
            }else if(current_block_type == 1){
                current_color = "#00ff00"
            }else if(current_block_type == 2){
                current_color = "#1b00ff"
            }else if(current_block_type == 3){
                current_color = "#fdaa00"
            }else if(current_block_type == 4){
                current_color = "#9900fc"
            }else if(current_block_type == 5){
                current_color = "#ffff00"
            }else if(current_block_type == 6){
                current_color = "#07feff"
            }
            current_spin_center=[4,1];
            current_block=statetoblock(statelist(0,current_block_type),current_spin_center);
            rotate_state_type=0;
            nextblock();
            blockupdate();
            already_hold=0;
        }
        function nextblock(){
            for(var i=0;i<4;i++){
                next_block_bag[i]=next_block_bag[i+1];
            }
            next_block_bag[4]=bag[block_cnt%8];
            block_cnt++;
            if(block_cnt%8==0)
                randomblock();
            for(var i=11;i<17;i++){
                for(var j=1;j<20;j++){
                    drawrect(i,j,"#c0c0c0",5,"#a0a0a0",0);
                }
            }
            for(var w=0;w<5;w++){
                var next_block_type=next_block_bag[w];
                var next_color;
                if(next_block_type == 0){
                    next_color = "#ff0000"
                }else if(next_block_type == 1){
                    next_color = "#00ff00"
                }else if(next_block_type == 2){
                    next_color = "#1b00ff"
                }else if(next_block_type == 3){
                    next_color = "#fdaa00"
                }else if(next_block_type == 4){
                    next_color = "#9900fc"
                }else if(next_block_type == 5){
                    next_color = "#ffff00"
                }else if(next_block_type == 6){
                    next_color = "#07feff"
                }
                var next_block=statelist(0,next_block_type);
                for(var i=0;i<4;i++){
                    drawrect(next_block[i][0]+13,next_block[i][1]+4+w*3,next_color,5,"#0f0f0f",0);
                    drawrect(next_block[i][0]+13,next_block[i][1]+4+w*3,next_color,5,secondcolor(next_color),5);
                }
            }
        }
        function secondcolor(color){
            if(color == "#ff0000"){
                return "#cf0000"
            }else if(color == "#00ff00"){
                return "#00cf00"
            }else if(color == "#1b00ff"){
                return "#1800cf"
            }else if(color == "#fdaa00"){
                return "#cd8600"
            }else if(color == "#9900fc"){
                return "#7600cc"
            }else if(color == "#ffff00"){
                return "#cfcf00"
            }else if(color == "#07feff"){
                return "#06cecf"
            }else if(color == "#c0c0c0"){
                return "#909090"
            }
        }
        function hold(){
            if(already_hold) return;
            already_hold=1;
            if(hold_block_type!=-1){
                var temp=current_block_type;
                current_block_type=hold_block_type;
                hold_block_type=temp;
                current_color=hold_color;
                current_spin_center=[4,1];
                current_block=statetoblock(statelist(0,current_block_type),current_spin_center);
                rotate_state_type=0;
                blockupdate();
            }else{
                hold_block_type=current_block_type;
                newblock();
            }
            for(var i=-7;i<-1;i++){
                for(var j=1;j<7;j++){
                    drawrect(i,j,"#c0c0c0",5,"#a0a0a0",0);
                }
            }
            if(hold_block_type == 0){
                hold_color = "#ff0000"
            }else if(hold_block_type == 1){
                hold_color = "#00ff00"
            }else if(hold_block_type == 2){
                hold_color = "#1b00ff"
            }else if(hold_block_type == 3){
                hold_color = "#fdaa00"
            }else if(hold_block_type == 4){
                hold_color = "#9900fc"
            }else if(hold_block_type == 5){
                hold_color = "#ffff00"
            }else if(hold_block_type == 6){
                hold_color = "#07feff"
            }
            var hold_block=statelist(0,hold_block_type);
            for(var i=0;i<4;i++){
                drawrect(hold_block[i][0]-5,hold_block[i][1]+4,hold_color,5,"#0f0f0f",0);
                drawrect(hold_block[i][0]-5,hold_block[i][1]+4,hold_color,5,secondcolor(hold_color),5);
            }
        }
        //blockrotate
        function rotate(direction){
            already_rotate=1;
            if(current_color=="#ffff00"){
                return;
            }else if(current_color=="#07feff"){
                var order=[];
                if(rotate_state_type==0){
                    if(direction==1){
                        order=[[-2,0],[1,0],[-2,1],[1,-2]];
                    }else{
                        order=[[-1,0],[2,0],[-1,-2],[2,1]];
                    }
                }else if(rotate_state_type==1){
                    if(direction==1){
                        order=[[-1,0],[2,0],[-1,-2],[2,1]];
                    }else{
                        order=[[2,0],[-1,0],[2,-1],[-1,2]];
                    }
                }else if(rotate_state_type==2){
                    if(direction==1){
                        order=[[2,0],[-1,0],[2,-1],[-1,2]];
                    }else{
                        order[[1,0],[-2,0],[1,2],[-2,-1]];
                    }
                }else if(rotate_state_type==3){
                    if(direction==1){
                        order=[[1,0],[-2,0],[1,2],[-2,-1]];
                    }else{
                        order[[-2,0],[1,0],[-2,1],[1,-2]];
                    }
                }
                current_block=rotatefittest(order,(rotate_state_type+direction)%4,current_block_type);
            }else{
                var order=[];
                if(rotate_state_type==0){
                    if(direction==1){
                        order=[[-1,0],[-1,-1],[0,2],[-1,2]];
                    }else{
                        order=[[1,0],[1,-1],[0,2],[1,2]];
                    }
                }else if(rotate_state_type==1){
                    order=[[1,0],[1,1],[0,-2],[1,-2]];
                }else if(rotate_state_type==2){
                    if(direction==1){
                        order=[[1,0],[1,-1],[0,2],[1,2]];
                    }else{
                        order[[-1,0],[-1,-1],[0,2],[-1,2]];
                    }
                }else if(rotate_state_type==3){
                    order=[[-1,0],[-1,1],[0,-2],[-1,-2]];
                }
                current_block=rotatefittest(order,(rotate_state_type+direction)%4,current_block_type);
            }
            if(already_rotate){
                rotate_state_type+=direction;
                rotate_state_type%=4;
            }
        }
        function statelist(rotatestatetype,blocktype){
            if(blocktype==0){
                if(rotatestatetype==0){
                    return [[-1,-1],[0,-1],[0,0],[1,0]];
                }else if(rotatestatetype==1){
                    return [[1,-1],[0,0],[1,0],[0,1]];
                }else if(rotatestatetype==2){
                    return [[-1,0],[0,0],[0,1],[1,1]];
                }else if(rotatestatetype==3){
                    return [[0,-1],[-1,0],[0,0],[-1,1]];
                }
            }else if(blocktype==1){
                if(rotatestatetype==0){
                    return [[0,-1],[1,-1],[-1,0],[0,0]];
                }else if(rotatestatetype==1){
                    return [[0,-1],[0,0],[1,0],[1,1]];
                }else if(rotatestatetype==2){
                    return [[0,0],[1,0],[-1,1],[0,1]];
                }else if(rotatestatetype==3){
                    return [[-1,-1],[-1,0],[0,0],[0,1]];
                }
            }else if(blocktype==2){
                if(rotatestatetype==0){
                    return [[-1,-1],[-1,0],[0,0],[1,0]];
                }else if(rotatestatetype==1){
                    return [[0,-1],[1,-1],[0,0],[0,1]];
                }else if(rotatestatetype==2){
                    return [[-1,0],[0,0],[1,0],[1,1]];
                }else if(rotatestatetype==3){
                    return [[0,-1],[0,0],[-1,1],[0,1]];
                }
            }else if(blocktype==3){
                if(rotatestatetype==0){
                    return [[1,-1],[-1,0],[0,0],[1,0]];
                }else if(rotatestatetype==1){
                    return [[0,-1],[0,0],[0,1],[1,1]];
                }else if(rotatestatetype==2){
                    return [[-1,0],[0,0],[1,0],[-1,1]];
                }else if(rotatestatetype==3){
                    return [[-1,-1],[0,-1],[0,0],[0,1]];
                }
            }else if(blocktype==4){
                if(rotatestatetype==0){
                    return [[0,-1],[-1,0],[0,0],[1,0]];
                }else if(rotatestatetype==1){
                    return [[0,-1],[0,0],[1,0],[0,1]];
                }else if(rotatestatetype==2){
                    return [[-1,0],[0,0],[1,0],[0,1]];
                }else if(rotatestatetype==3){
                    return [[0,-1],[-1,0],[0,0],[0,1]];
                }
            }else if(blocktype==5){
                return [[0,-1],[1,-1],[0,0],[1,0]];
            }else if(blocktype==6){
                if(rotatestatetype==0){
                    return [[-1,0],[0,0],[1,0],[2,0]];
                }else if(rotatestatetype==1){
                    return [[1,-1],[1,0],[1,1],[1,2]];
                }else if(rotatestatetype==2){
                    return [[-1,1],[0,1],[1,1],[2,1]];
                }else if(rotatestatetype==3){
                    return [[0,-1],[0,0],[0,1],[0,2]];
                }
            }
        }
        function statetoblock(rotatearray,spincenter){
            var rotate_block=[];
            rotate_block=rotatearray;
            for(var i=0;i<4;i++){
                rotate_block[i][0]+=spincenter[0];
                rotate_block[i][1]+=spincenter[1];
            }
            return rotate_block;
        }
        function rotatefittest(order,rotatestate,blocktype){
            var rotatearray=statelist(rotatestate,blocktype);
            var rotate_test_block=statetoblock(rotatearray,current_spin_center);
            if(rotateblockfit(rotate_test_block)){
                return rotate_test_block;
            }
            for(var i=0;i<4;i++){
                rotatearray=statelist(rotatestate,blocktype);
                var x=order[i][0],y=order[i][1];
                current_spin_center[0]+=x;
                current_spin_center[1]+=y;
                rotate_test_block=statetoblock(rotatearray,current_spin_center);
                if(rotateblockfit(rotate_test_block)){
                    return rotate_test_block;
                }
                current_spin_center[0]-=x;
                current_spin_center[1]-=y;
            }
            already_rotate=0;
            return current_block;
        }
        function rotateblockfit(rotateblock){
            var can_rotate=1;
            for(var i=0;i<4;i++){
                if(rotateblock[i][0]<0 || rotateblock[i][0]>9 || rotateblock[i][1]<0 || rotateblock[i][1]>19) can_rotate=0;
                else if(arr[rotateblock[i][0]][rotateblock[i][1]]!="#c0c0c0") can_rotate=0;
            }
            return can_rotate;
        }
        //score
        function cleanline(){
            var clean=1;
            var clean_count=0;
            for(var j=0;j<20;j++){
                clean=1;
                for(var i=0;i<10;i++)
                    if(arr[i][j]=="#c0c0c0")
                        clean=0;
                if(clean){
                    for(var k=j;k>0;k--)
                        for(var l=0;l<10;l++)
                            arr[l][k]=arr[l][k-1];
                    line++;
                    clean_count++;
                }
            }
            level=Math.floor(line/10)+1;
            gamespeed=1000-20*level;
            var is_tspin=0;
            if(current_block_type==4){
                if(rotate_state_type==0 && (arr[current_spin_center[0]-1][current_spin_center[1]-1]!="#c0c0c0" || arr[current_spin_center[0]][current_spin_center[1]-2]!="#c0c0c0" || arr[current_spin_center[0]+1][current_spin_center[1]-1]!="#c0c0c0"))
                    is_tspin=1;
                if(rotate_state_type==1 && (arr[current_spin_center[0]][current_spin_center[1]-2]!="#c0c0c0" || arr[current_spin_center[0]+1][current_spin_center[1]-1]!="#c0c0c0"))
                    is_tspin=1;
                if(rotate_state_type==2 && (arr[current_spin_center[0]-1][current_spin_center[1]-1]!="#c0c0c0" || arr[current_spin_center[0]][current_spin_center[1]-1]!="#c0c0c0" || arr[current_spin_center[0]+1][current_spin_center[1]-1]!="#c0c0c0"))
                    is_tspin=1;
                if(rotate_state_type==3 && (arr[current_spin_center[0]-1][current_spin_center[1]-1]!="#c0c0c0" || arr[current_spin_center[0]][current_spin_center[1]-2]!="#c0c0c0"))
                    is_tspin=1;
            }
            if(is_tspin){
                if(clean_count==1) score+=800*level;
                if(clean_count==2) score+=1200*level;
                if(clean_count==3) score+=1600*level;
                if(back_to_back){
                    if(clean_count==1) score+=400*level;
                    if(clean_count==2) score+=600*level;
                    if(clean_count==3) score+=800*level;
                }
                back_to_back=1;
            }else{
                if(clean_count==1) score+=100*level,back_to_back=0;
                if(clean_count==2) score+=300*level,back_to_back=0;
                if(clean_count==3) score+=500*level,back_to_back=0;
                if(clean_count==4){
                    score+=800*level;
                    if(back_to_back)
                        score+=400*level;
                    back_to_back=1;
                }
            }
            scoreupdate();
        }
        //canvas update
        function scoreupdate(){
            for(var i=-7;i<-1;i++){
                for(var j=11;j<20;j++){
                    drawrect(i,j,"#c0c0c0",5,"#a0a0a0",0);
                }
            }
            ctx.font = '20pt monospace';
            ctx.lineWidth = 2;
            ctx.strokeStyle = "#000000";
            ctx.strokeText("Level", 90, 375);
            ctx.strokeText("Score", 90, 465);
            ctx.strokeText("Line", 95, 555);
            ctx.font = '30pt Calibri';
            ctx.strokeText(level, 120-10*Math.floor(Math.log10(level)), 425);
            if(score==0) ctx.strokeText(score, 120, 515);
            ctx.strokeText(score, 120-10*Math.floor(Math.log10(score)), 515);
            if(line==0) ctx.strokeText(line, 120, 605);
            ctx.strokeText(line, 120-10*Math.floor(Math.log10(line)), 605);
        }
        function blockupdate(){
            for(var i=0;i<10;i++){
                for(var j=0;j<20;j++){
                    drawrect(i,j,arr[i][j],5,"#0f0f0f",0);
                    drawrect(i,j,arr[i][j],5,secondcolor(arr[i][j]),5);
                }
            }
            for(var i=0;i<4;i++){
                drawrect(current_block[i][0],current_block[i][1],current_color,5,"#ffffff",0);
                drawrect(current_block[i][0],current_block[i][1],current_color,5,secondcolor(current_color),5);
            }
        }
        //drawing tools
        function drawcircle(x,y,radius,color){
            ctx.beginPath();
            ctx.arc(x, y, radius, 0, 2 * Math.PI);
            ctx.fillStyle=color;
            ctx.fill();
        }
        function drawrect(x,y,color,width,widthcolor,margin){
            ctx.beginPath();
            ctx.rect(250+x*30+margin, 20+y*30+margin, 30-2*margin, 30-2*margin);
            ctx.fillStyle = color;
            ctx.fill();
            ctx.lineWidth = width;
            ctx.strokeStyle = widthcolor;
            ctx.stroke();
        }
    </script>
</body>
</html>

實作 #3

我們來做彈珠台吧

彈珠台怎麼做

簡單來說:

分為球與釘子兩大部分

基本上只要處理以下這些

初始化釘、初始化球、釘球碰撞、牆球碰撞、球球碰撞

然後處理碰撞可能需要用到高中數學技巧

物理引擎

喔就是每顆球都有好多參數

x座標、y座標、x軸方向速度、y軸方向速度、

x軸方向加速度、y軸方向加速度等

然後碰撞的時候就好好維護這些變數就好惹

可以把釘子跟牆壁固定把球的運動當反射

兩個球互相碰撞再用動量守恆來計算

初始化

        //marble generate
        function marble(){
            this.x=Math.random()*680+160;
            this.y=30;
            this.vx=Math.random()*2-1;
            this.vy=Math.random()*2-1;
            this.ay=0.005;
        }
        var marbles = [], marble_num = 0;
        function init_marble(){
            marble_num = 0
            for(var i=0;i<31;i++){
                marbles[marble_num++] = new marble();
            }
        }

        //nail generate
        function nail(x, y){
            this.x=x;
            this.y=y;
        }
        var nails = [], nail_cnt = 0;
        var nail_row = [5,6,7,6,7,6,7];
        for(var i=0;i<7;i++){
            for(var j=0;j<nail_row[i];j++){
                nails[nail_cnt++] = new nail((7-nail_row[i])*50+j*100+202, i*100+150);
            }
        }
        for(var j=0;j<7;j++){
            for(var i=0;i<11;i++){
                nails[nail_cnt++] = new nail(i*71+145, 870+20*j);
            }
        }

直接附扣的

<!DOCTYPE HTML>
<html>

<head>
    <title>Youtube - 酷欸</title>
    <link rel="icon" href="https://play-lh.googleusercontent.com/lMoItBgdPPVDJsNOVtP26EKHePkwBg-PkuY9NOrc-fumRtTFP4XhpUNk_22syN4Datc"/> 
</head>

<body data-rsssl=1>
    <canvas id="myCanvas" width="1500" height="1100"></canvas>
        
    <script>
        var canvas = document.getElementById('myCanvas');
        var ctx = canvas.getContext('2d');
        
        var width = 1500;
        var height = 1100;
            
        //marble generate
        function marble(){
            this.x=Math.random()*680+160;
            this.y=30;
            this.vx=Math.random()*2-1;
            this.vy=Math.random()*2-1;
            this.ay=0.005;
        }
        var marbles = [], marble_num = 0;
        function init_marble(){
            marble_num = 0
            for(var i=0;i<31;i++){
                marbles[marble_num++] = new marble();
            }
        }

        //nail generate
        function nail(x, y){
            this.x=x;
            this.y=y;
        }
        var nails = [], nail_cnt = 0;
        var nail_row = [5,6,7,6,7,6,7];
        for(var i=0;i<7;i++){
            for(var j=0;j<nail_row[i];j++){
                nails[nail_cnt++] = new nail((7-nail_row[i])*50+j*100+202, i*100+150);
            }
        }
        for(var j=0;j<7;j++){
            for(var i=0;i<11;i++){
                nails[nail_cnt++] = new nail(i*71+145, 870+20*j);
            }
        }

        //wooden texture generate
        function wooden_texture(y){
            this.x=Math.random()*725+135;
            this.y=y;
            this.vy=Math.random()*0.5;
        }
        var wooden_textures = [];
        for(var i=0;i<100;i++){
            wooden_textures[i] = new wooden_texture(Math.random()*1000);
        }

        function redrop(arr){
            for(var i=0;i<arr.length;i++){
                marbles[arr[i]-1] = new marble();
            }
        }
        function pos_update(item){
            item.x+=item.vx;
            item.y+=item.vy;
            item.vy+=item.ay;
        }
        function wall_hit(item){
            if((item.x>840 && item.vx>0) || (item.x<160 && item.vx<0)){
                item.vx*=-0.98;
                if(item.y>870){
                    item.vx*=0.9;
                }
            }
            if((item.y>975 && item.vy>0) || (item.y<25 && item.vy<0)){
                item.vy*=-0.98;
                if(item.y>975){
                    item.vy*=0.9;
                }
            }
            if(item.y>975){
                item.y=975;
            }
        }
        function nail_hit(marble){
            for(var i=0;i<nail_cnt;i++){
                if((marble.x-nails[i].x)*(marble.x-nails[i].x)+(marble.y-nails[i].y)*(marble.y-nails[i].y)<=1200 && (marble.x-nails[i].x)*(marble.x-nails[i].x)+(marble.y-nails[i].y)*(marble.y-nails[i].y)>=(marble.x+marble.vx-nails[i].x)*(marble.x+marble.vx-nails[i].x)+(marble.y+marble.vy-nails[i].y)*(marble.y+marble.vy-nails[i].y)){
                    var t = (marble.y-nails[i].y)/(marble.x-nails[i].x);
                    var cos = (1-t*t)/(1+t*t);
                    var sin = (2*t)/(1+t*t);
                    var rpos = {
                        x:(cos*marble.vx+sin*marble.vy),
                        y:(sin*marble.vx-cos*marble.vy)
                    }
                    marble.vx=-0.98*rpos.x;
                    marble.vy=-0.98*rpos.y;
                    if(i>43){
                        marble.vx*=0.9;
                        marble.vy*=0.9;
                    }
                }
            }
        }
        function marble_hit(marble1,marble2){
            if((marble1.x-marble2.x)*(marble1.x-marble2.x)+(marble1.y-marble2.y)*(marble1.y-marble2.y)<=2500 && (marble1.x+marble1.vx-marble2.x-marble2.vx)*(marble1.x+marble1.vx-marble2.x-marble2.vx)+(marble1.y+marble1.vy-marble2.y-marble2.vy)*(marble1.y+marble1.vy-marble2.y-marble2.vy)<=(marble1.x-marble2.x)*(marble1.x-marble2.x)+(marble1.y-marble2.y)*(marble1.y-marble2.y)){
                var rpos = {
                    x:marble1.x-marble2.x,
                    y:marble1.y-marble2.y
                };
                var v1={
                    x:(marble1.vx*rpos.x+marble1.vy*rpos.y)/(rpos.x*rpos.x+rpos.y*rpos.y)*rpos.x,
                    y:(marble1.vx*rpos.x+marble1.vy*rpos.y)/(rpos.x*rpos.x+rpos.y*rpos.y)*rpos.y
                }
                var v2={
                    x:(marble2.vx*rpos.x+marble2.vy*rpos.y)/(rpos.x*rpos.x+rpos.y*rpos.y)*rpos.x,
                    y:(marble2.vx*rpos.x+marble2.vy*rpos.y)/(rpos.x*rpos.x+rpos.y*rpos.y)*rpos.y
                }
                marble1.vx+=v2.x-v1.x;
                marble1.vy+=v2.y-v1.y;
                marble2.vx+=v1.x-v2.x;
                marble2.vy+=v1.y-v2.y;
                marble1.vx*=0.98;
                marble1.vy*=0.98;
                marble2.vx*=0.98;
                marble2.vy*=0.98;
                if(marble1.y>870){
                    marble1.vy*=0.98;
                }
                if(marble2.y>870){
                    marble2.vy*=0.98;
                }
                pos_update(marble1);
                pos_update(marble2);
            }
        }
        var time=0;
        init_marble();
        draw_rect(0,0,1000,1100,"#333333", 0, "#ffffff");
        setInterval(function(){
            time++;
            if(time%2==0){
                draw_rect(135,0,865,1000,"#dcb284", 0, "#ffffff");
            }
            for(var i=0;i<100;i++){
                if(time%2==0){draw_rect(wooden_textures[i].x,wooden_textures[i].y,wooden_textures[i].x+5,Math.min(1000,wooden_textures[i].y+100),"#cca274", 0, "#cca274");}
                wooden_textures[i].y-=wooden_textures[i].vy;
                if(wooden_textures[i].y<-100){
                    wooden_textures[i] = new wooden_texture(1000);
                }
            }
            for(var i=0;i<marble_num;i++){
                if(time%2==0){draw_marble(marbles[i].x, marbles[i].y, i+1);}
                for(var j=i+1;j<marble_num;j++){
                    marble_hit(marbles[i], marbles[j]);
                }
                pos_update(marbles[i]);
                wall_hit(marbles[i]);
                nail_hit(marbles[i]);
            }
            for(var i=0;i<nail_cnt;i++){
                if(time%2==0){draw_nail(nails[i].x, nails[i].y);}
            }
        },1)
        function draw_marble(x,y,i){
            ctx.beginPath();
            ctx.arc(x, y, 25, 0, 2 * Math.PI);
            ctx.fillStyle="#000000";
            ctx.fill();
            ctx.beginPath();
            ctx.arc(x, y, 24, 0, 2 * Math.PI);
            ctx.fillStyle="#ff9922";
            ctx.fill();
            ctx.beginPath();
            ctx.arc(x-3, y-3, 20, 0, 2 * Math.PI);
            ctx.fillStyle="#ffbb77";
            ctx.fill();
            ctx.font = '20pt Calibri bold';
            ctx.fillStyle = "#000000";
            if(i<10){
                ctx.fillText(i, x-8, y+10);
            }else{
                ctx.fillText(i, x-15, y+10);
            }
        }
        function draw_nail(x,y){
            ctx.beginPath();
            ctx.arc(x, y, 10, 0, 2 * Math.PI);
            ctx.fillStyle="#777777";
            ctx.fill();
            ctx.beginPath();
            ctx.arc(x, y, 6, 0, 2 * Math.PI);
            ctx.fillStyle="#555555";
            ctx.fill();
        }
        function draw_rect(x1,y1,x2,y2,color,width,widthcolor){
            ctx.beginPath();
            ctx.rect(x1,y1,x2-x1,y2-y1);
            ctx.fillStyle = color;
            ctx.fill();
            ctx.lineWidth = width;
            ctx.strokeStyle = widthcolor;
            ctx.stroke();
        }
    </script>
</body>

</html>

資訊素養補給站

RGB色碼

電腦螢幕放很大會看到紅綠藍三色

常用的表示法:24位元模式

R, G, B 三色各用8個位元表示\((0\sim 2^{8}-1)\)

0~255用16進位表示就只有兩位了

0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F

#F4A751 = rgb(244, 167, 81)

#00A7AC = rgb(0, 167, 172)

Finish

RGBA色碼

a是alpha,透明度

32個位元儲存

#FFFF0050 = rgba(255, 255, 0, 80)

 

Finish

Made with Slides.com