資訊社放學社課-網頁
講師:王政凱
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 樣式
<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>😛</p>
<p>🦖</p>
<p>🦄</p>
<p>🌍</p>
<p>🌎</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
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
資訊社放學社課-網頁
By ck_platypus
資訊社放學社課-網頁
- 1,306