利用酷酷的 Processing 寫出 Flappy Bird!
void setup(){
// 開始畫畫前的準備
// 畫筆粗細、背景顏色、畫框大小等等
// 只會執行一次
}
void draw(){
// 緊接在 setup 函數後執行
// 開始不斷地作畫
// 在程式中會不斷執行
// 每執行一次就是一個畫面 (一幀)
}
蛤?
void setup() 是什麼
void setup() 是什麼
回傳型態
函數名稱
傳入變數
蛤?型態?變數?
int: 整數
float: 小數
boolean: 布林代數 (真或假)
String: 字串 (一串文字)
int x = 10;
資料型態
變數名稱
變數值
float pi = 3.14159;
資料型態
變數名稱
變數值
boolean processing_is_easy = true;
資料型態
變數名稱
變數值
String name = "NYCU_twyc";
資料型態
變數名稱
變數值
開頭第一個字元不能是數字 ( 2car )
processing_is_fun (snake_case)
processingIsFun (camelCase)
void setup()
int add(int x, int y)
回傳的資料型態為整數 (int)
傳入兩個整數 x 和 y
int add(int x, int y){
return x + y;
}
回傳右邊的計算出的數值
{ } 為函數的範圍
300
300
200
200
void setup(){
// 視窗大小為 300 x 300
size(300, 300);
// 繪製一個左上角座標為 (50, 50)
// 長寬為 200 的長方形
// YOUR CODE HERE //
}
void draw(){
// skip
}
void setup(){
// 視窗大小為 300 x 300
size(300, 300);
// 繪製一個左上角座標為 (50, 50)
// 長寬為 200 的長方形
// YOUR CODE HERE //
}
void draw(){
// skip
}
(A) rect(200, 50, 50, 200);
(C) rect(50, 50, 200, 200);
(B) rect(200, 200, 50, 50);
(D) rect(50, 200, 50, 200);
void setup(){
// 視窗大小為 300 x 300
size(300, 300);
// 繪製一個左上角座標為 (50, 50)
// 長寬為 200 的長方形
// YOUR CODE HERE //
}
void draw(){
// skip
}
(A) rect(200, 50, 50, 200);
(C) rect(50, 50, 200, 200);
(B) rect(200, 200, 50, 50);
(D) rect(50, 200, 50, 200);
void setup(){
// 視窗大小為 300 x 300
size(300, 300);
// 繪製一個左上角座標為 (50, 50)
// 長寬為 200 的長方形
rect(50, 50, 200, 200);
}
void draw(){
// skip
}
rect(a, b, c, d)
rect(a, b, c, d)
a: 長方形的 x 座標
b: 長方形的 y 座標
c: 長方形的寬
d: 長方形的高
rect(a, b, c, d)
a: 長方形的 x 座標
b: 長方形的 y 座標
c: 長方形的寬
d: 長方形的高
執行
(50, 50)
(300, 300)
(0, 0)
一個會跟著滑鼠跑的正方形
void setup(){
size(800, 800);
background(255, 255, 255);
noFill(); // 不填色
strokeWeight(5); // 長方形線寬
}
void draw(){
// YOUR CODE HERE //
}
void setup(){
size(800, 800);
background(255, 255, 255);
noFill(); // 不填色
strokeWeight(5); // 長方形線寬
}
void draw(){
// YOUR CODE HERE //
}
void setup(){
size(800, 800);
background(255, 255, 255);
noFill(); // 不填色
strokeWeight(5); // 長方形線寬
}
void draw(){
// YOUR CODE HERE //
}
(C) rect(mouseX, 50, mouseY, 50);
(D) rect(50, mouseX, 50, mouseY);
(A) rect(mouseX, mouseY, 50, 50);
(B) rect(50, 50, mouseX, mouseY);
mouseX: 滑鼠的 X 座標
mouseY: 滑鼠的 Y 座標
void setup(){
size(800, 800);
background(255, 255, 255);
noFill(); // 不填色
strokeWeight(5); // 長方形線寬
}
void draw(){
rect(mouseX, mouseY, 50, 50);
}
(A) rect(mouseX, mouseY, 50, 50);
(C) rect(mouseX, 50, mouseY, 50);
(B) rect(50, 50, mouseX, mouseY);
(D) rect(50, mouseX, 50, mouseY);
?
?
出現許多重複的正方形
?
出現許多重複的正方形
把原本畫的正方形蓋掉
void setup(){
size(800, 800);
background(255, 255, 255);
noFill(); // 不填色
strokeWeight(5); // 長方形線寬
}
void draw(){
// YOUR CODE HERE //
// mouseX, mouseY 代表滑鼠的 x 和 y 座標
rect(mouseX, mouseY, 100, 100);
}
(A) fill(255, 255, 255); rect(0, 0, 800, 800);
(B) background(255, 255, 255);
void setup(){
size(800, 800);
background(255, 255, 255);
noFill(); // 不填色
strokeWeight(5); // 長方形線寬
}
void draw(){
// YOUR CODE HERE //
// mouseX, mouseY 代表滑鼠的 x 和 y 座標
rect(mouseX, mouseY, 100, 100);
}
(A) fill(255, 255, 255); rect(0, 0, 800, 800);
(B) background(255, 255, 255);
void setup(){
size(800, 800);
background(255, 255, 255);
noFill(); // 不填色
strokeWeight(5); // 長方形線寬
}
void draw(){
background(255, 255, 255);
// mouseX, mouseY 代表滑鼠的 x 和 y 座標
rect(mouseX, mouseY, 100, 100);
}
(A) 方法會在畫面外緣加入一個外框,可以查一下怎麼移除
void setup(){
size(800, 800);
background(255, 255, 255);
noFill(); // 不填色
strokeWeight(5); // 長方形線寬
rectMode(CENTER); // 座標代表長方形中間位置
}
void draw(){
background(255, 255, 255);
// mouseX, mouseY 代表滑鼠的 x 和 y 座標
rect(mouseX, mouseY, 100, 100);
}
讓滑鼠黏在正方形的中間
rectMode(CORNER)
rectMode(CENTER)
color red = color(255, 0, 0);
color green = color(0, 255, 0);
color blue = color(0, 0, 255);
void setup(){
size(900, 900);
strokeWeight(5); // 長方形線寬
}
void draw(){
if ( ??? ) {
background(red);
} else if ( ??? ) {
background(green);
} else if ( ??? ){
background(blue);
}
line(300, 0, 300, 900);
line(600, 0, 600, 900);
}
line(a, b, c, d)
(a, b) 第一個點的座標
(c, d) 第二個點的座標
if ( condition 1 ) {
// 做某些事
}
如果 condition 1 成立
那就進行 { } 裡面的程式碼
if ( 今天出大太陽 ) {
出去玩一波大的;
}
if ( condition 1 ) {
// do something
} else {
// do something else
}
如果 condition 1 成立
那就進行 { } 裡面的程式碼
否則執行 else 後面 { } 裡面的程式碼
if ( 今天出大太陽 ) {
出去玩一波大的;
} else {
在宿舍睡一波大的;
}
if ( condition 1 ) {
// ...
} else if ( condition 2 ) {
// ...
} else {
// ...
}
如果 condition 1 成立,那就執行 condition 1 中的程式碼
如果不成立,則檢查 condition 2 是否成立
如果成立則執行 condition 2 中的程式碼
若 condition 1 和 2 都不成立,則執行 else 中的程式碼
if ( 今天出大太陽 ) {
出去完一波大的;
} else if ( 明天要考試 ) {
去圖書館讀書;
} else {
在宿舍睡一波大的;
}
if ( ... ) {
} else if ( ... ) {
} else if ( ... ){
} else {
}
if ( condition 1 ) {
if ( condition 2 ) {
} else {
}
}
if ( 今天出大太陽 ) {
if ( 今天有放假 ) {
直接玩個兩天;
} else {
去動物園看紅毛猩猩;
}
}
運算子 | 名稱 |
---|---|
== | 等於 |
!= | 不等於 |
>= | 大於等於 |
<= | 小於等於 |
> | 大於 |
< | 小於 |
int x = 1; x == 1 (true) x >= 1 (true) x > 1 (false) x != 2 (true) x <= 10 (true)
運算子 | 名稱 |
---|---|
&& | 且 |
|| | 或 |
! | 否定 |
A | B | A && B |
---|---|---|
True | True | True |
True | False | False |
False | True | False |
False | False | False |
A | B | A || B |
---|---|---|
True | True | True |
True | False | True |
False | True | True |
False | False | False |
A | !A |
---|---|
True | False |
False | True |
color red = color(255, 0, 0);
color green = color(0, 255, 0);
color blue = color(0, 0, 255);
void setup(){
size(900, 900);
strokeWeight(5); // 長方形線寬
}
void draw(){
if ( (1) ) {
background(red);
} else if ( (2) ) {
background(green);
} else if ( (3) ){
background(blue);
}
line(300, 0, 300, 900);
line(600, 0, 600, 900);
}
0 <= mouseX < 300
300 <= mouseX < 600
600 <= mouseX < 900
color red = color(255, 0, 0);
color green = color(0, 255, 0);
color blue = color(0, 0, 255);
void setup(){
size(900, 900);
strokeWeight(5); // 長方形線寬
}
void draw(){
if ( 0 <= mouseX < 300 ) {
background(red);
} else if ( 300 <= mouseX < 600 ) {
background(green);
} else if ( 600 <= mouseX < 900 ){
background(blue);
}
line(300, 0, 300, 900);
line(600, 0, 600, 900);
}
0 <= mouseX < 300
300 <= mouseX < 600
600 <= mouseX < 900
0 <= mouseX < 300
300 <= mouseX < 600
600 <= mouseX < 900
color red = color(255, 0, 0);
color green = color(0, 255, 0);
color blue = color(0, 0, 255);
void setup(){
size(900, 900);
strokeWeight(5); // 長方形線寬
}
void draw(){
if ( 0 <= mouseX < 300 ) {
background(red);
} else if ( 300 <= mouseX < 600 ) {
background(green);
} else if ( 600 <= mouseX < 900 ){
background(blue);
}
line(300, 0, 300, 900);
line(600, 0, 600, 900);
}
color red = color(255, 0, 0);
color green = color(0, 255, 0);
color blue = color(0, 0, 255);
void setup(){
size(900, 900);
strokeWeight(5); // 長方形線寬
}
void draw(){
if ( (1) ) {
background(red);
} else if ( (2) ) {
background(green);
} else if ( (3) ){
background(blue);
}
line(300, 0, 300, 900);
line(600, 0, 600, 900);
}
0 <= mouseX && mouseX < 300
300 <= mouseX && mouseX < 600
600 <= mouseX && mouseX < 900
color red = color(255, 0, 0);
color green = color(0, 255, 0);
color blue = color(0, 0, 255);
void setup(){
size(900, 900);
strokeWeight(5); // 長方形線寬
}
void draw(){
if ( 0 <= mouseX && mouseX < 300 ) {
background(red);
} else if ( 300 <= mouseX && mouseX < 600 ) {
background(green);
} else if ( 600 <= mouseX && mouseX < 900 ){
background(blue);
}
line(300, 0, 300, 900);
line(600, 0, 600, 900);
}
0 <= mouseX && mouseX < 300
300 <= mouseX && mouseX < 600
600 <= mouseX && mouseX < 900
color red = color(255, 0, 0);
color green = color(0, 255, 0);
color blue = color(0, 0, 255);
void setup(){
size(900, 900);
strokeWeight(5); // 長方形線寬
}
void draw(){
if ( 0 <= mouseX && mouseX < 300 ) {
background(red);
} else if ( 300 <= mouseX && mouseX < 600 ) {
background(green);
} else if ( 600 <= mouseX && mouseX < 900 ){
background(blue);
}
line(300, 0, 300, 900);
line(600, 0, 600, 900);
}
可以更簡化嗎?
color red = color(255, 0, 0);
color green = color(0, 255, 0);
color blue = color(0, 0, 255);
void setup(){
size(900, 900);
strokeWeight(5); // 長方形線寬
}
void draw(){
if ( mouseX < 300 ) {
background(red);
} else if ( mouseX < 600 ) {
background(green);
} else if ( mouseX < 900 ){
background(blue);
}
line(300, 0, 300, 900);
line(600, 0, 600, 900);
}
mouseX < 300
mouseX < 600
mouseX < 900
color red = color(255, 0, 0);
color green = color(0, 255, 0);
color blue = color(0, 0, 255);
void setup(){
size(900, 900);
strokeWeight(5); // 長方形線寬
}
void draw(){
if ( mouseX < 300 ) {
background(red);
} else if ( mouseX < 600 ) {
background(green);
} else {
background(blue);
}
line(300, 0, 300, 900);
line(600, 0, 600, 900);
}
void setup(){
size(800, 600); // 設定寬度為 800 pixel、長度為 600 pixel
background(255, 255, 255); // R, G, B
stroke(0, 0, 0); // R, G, B
strokeWeight(4); // 筆畫寬度
}
void draw(){
fill(0, 0, 0);
if(mousePressed){
// YOUR CODE HERE //
}
}
void setup(){
size(800, 600); // 設定寬度為 800 pixel、長度為 600 pixel
background(255, 255, 255); // R, G, B
stroke(0, 0, 0); // R, G, B
strokeWeight(4); // 筆畫寬度
}
void draw(){
fill(0, 0, 0);
if(mousePressed){
// YOUR CODE HERE //
}
}
(A) rect(mouseX, mouseY, 5, 5);
(B) circle(mouseX, mouseY, 5);
(C) line(0, 0, mouseX, mouseY);
(D) line(pmouseX, pmouseY, mouseX, mouseY);
void setup(){
size(800, 600); // 設定寬度為 800 pixel、長度為 600 pixel
background(255, 255, 255); // R, G, B
stroke(0, 0, 0); // R, G, B
strokeWeight(4); // 筆畫寬度
}
void draw(){
fill(0, 0, 0);
if(mousePressed){
// YOUR CODE HERE //
}
}
(A) rect(mouseX, mouseY, 5, 5);
(B) circle(mouseX, mouseY, 5);
(C) line(0, 0, mouseX, mouseY);
(D) line(pmouseX, pmouseY, mouseX, mouseY);
(pmouseX, pmouseY)
(mouseX, mouseY)
void setup(){
size(800, 600);
background(255, 255, 255); // R, G, B
stroke(0, 0, 0); // R, G, B
strokeWeight(4); // 寬度
}
void draw(){
if( mousePressed && ??? ){
stroke(0, 0, 0);
strokeWeight(4);
line(pmouseX, pmouseY, mouseX, mouseY);
} else if( mousePressed && ??? ){
stroke(255, 255, 255);
strokeWeight(20);
line(pmouseX, pmouseY, mouseX, mouseY);
}
}
void setup(){
size(800, 600);
background(255, 255, 255); // R, G, B
stroke(0, 0, 0); // R, G, B
strokeWeight(4); // 寬度
}
void draw(){
if( mousePressed && mouseButton == LEFT ){
stroke(0, 0, 0);
strokeWeight(4);
line(pmouseX, pmouseY, mouseX, mouseY);
} else if( mousePressed && mouseButton == RIGHT ){
stroke(255, 255, 255);
strokeWeight(20);
line(pmouseX, pmouseY, mouseX, mouseY);
}
}
如果要在小畫家上加一個指標
void setup(){
size(800, 600);
background(255, 255, 255); // R, G, B
stroke(0, 0, 0); // R, G, B
strokeWeight(4); // 寬度
}
void draw(){
if(mousePressed && mouseButton == LEFT){
strokeWeight(4);
stroke(0, 0, 0);
line(pmouseX, pmouseY, mouseX, mouseY);
} else if(mousePressed && mouseButton == RIGHT){
stroke(255, 255, 255);
strokeWeight(20);
line(pmouseX, pmouseY, mouseX, mouseY);
}
strokeWeight(2);
line(mouseX - 10, mouseY, mouseX + 10, mouseY);
line(mouseX, mouseY - 10, mouseX, mouseY + 10);
}
void setup(){
size(800, 600);
background(255, 255, 255); // R, G, B
stroke(0, 0, 0); // R, G, B
strokeWeight(4); // 寬度
}
void draw(){
background(255, 255, 255);
if(mousePressed && mouseButton == LEFT){
strokeWeight(4);
stroke(0, 0, 0);
line(pmouseX, pmouseY, mouseX, mouseY);
} else if(mousePressed && mouseButton == RIGHT){
stroke(255, 255, 255);
strokeWeight(20);
line(pmouseX, pmouseY, mouseX, mouseY);
}
strokeWeight(2);
line(mouseX - 10, mouseY, mouseX + 10, mouseY);
line(mouseX, mouseY - 10, mouseX, mouseY + 10);
}
把滑鼠的座標存下來,每次都重新畫
把滑鼠的座標存下來,每次都重新畫
每個座標都宣告兩個變數存
把滑鼠的座標存下來,每次都重新畫
可能有上萬個座標
把滑鼠的座標存下來,每次都重新畫
陣列 (Array) !
10 |
---|
int x = 10;
int x1 = 10;
int x2 = 15;
int x3 = 21;
int x4 = 17;
int x5 = 18;
10 |
---|
15 |
---|
21 |
---|
17 |
---|
18 |
---|
int[] x = new int[5];
10 | 15 | 21 | 17 | 18 |
---|
x[0]
x[1]
x[2]
x[3]
x[4]
int[] x = new int[5];
資料型態
[] 代表陣列
變數名稱
一個 "新" 的陣列
陣列中有幾個變數
for(int i=0;i<10;i=i+1)
初始
執行條件
每次進行一次迴圈的操作
void setup() {
int[] x = {1, 2, 3, 4, 5};
for(int i=0;i<x.length;i++){
println(x[i]);
}
}
void draw(){
// pass
}
可以使用 x.length 拿到陣列的大小
int[] px = new int[10000];
int[] py = new int[10000];
int[] x = new int[10000];
int[] y = new int[10000];
int idx = 0;
void setup(){
size(800, 600);
background(255, 255, 255); // R, G, B
stroke(0, 0, 0); // R, G, B
strokeWeight(5); // 寬度
noFill();
noCursor(); // 不顯示滑鼠鼠標
}
void draw(){
background(255, 255, 255); // R, G, B
if(mousePressed){
px[idx] = pmouseX;
py[idx] = pmouseY;
x[idx] = mouseX;
y[idx] = mouseY;
idx = idx + 1;
}
for(int i = 0; i < idx; i++) {
strokeWeight(5);
line(px[i], py[i], x[i], y[i]);
}
strokeWeight(2);
line(mouseX - 10, mouseY, mouseX + 10, mouseY);
line(mouseX, mouseY - 10, mouseX, mouseY + 10);
}
?
鳥往右飛
鳥往右飛
水管往左跑
鳥在同一個 x 座標上上下移動
水管往左跑
pillar[] p = new pillar[3];
boolean end = false;
boolean intro = true;
int score = 0;
PImage bg, bird, pillar_up, pillar_down;
void setup() {
bg = loadImage("background.jpg");
bird = loadImage("bird.png");
pillar_up = loadImage("pillar_up.png");
pillar_down = loadImage("pillar_down.png");
bg.resize(500, 800);
size(500, 800);
for (int i = 0; i < 3; i++) {
p[i] = new pillar(i);
}
}
void draw() {
background(bg);
for(int i=0;i<3;i++){
p[i].drawPillar();
}
for(int i=0;i<3;i++){
p[i].xPos -= 2;
}
}
class pillar {
float xPos, opening;
pillar(int i){
xPos = 100 + i * 200;
opening = 400;
}
void drawPillar() {
imageMode(CENTER);
image(pillar_up, xPos, opening - 100 - 350, 40, 700);
image(pillar_down, xPos, opening + 100 + 350, 40, 700);
}
}
opening
100 px
100 px
opening_half_width
顯示柱子
opening
100 px
100 px
350 px
中心點
顯示柱子
pillar[] p = new pillar[3];
boolean end = false;
boolean intro = true;
int score = 0;
PImage bg, bird, pillar_up, pillar_down;
void setup() {
bg = loadImage("background.jpg");
bird = loadImage("bird.png");
pillar_up = loadImage("pillar_up.png");
pillar_down = loadImage("pillar_down.png");
bg.resize(500, 800);
size(500, 800);
for (int i = 0; i < 3; i++) {
p[i] = new pillar(i);
}
}
void draw() {
background(bg);
for(int i=0;i<3;i++){
p[i].drawPillar();
}
for(int i=0;i<3;i++){
p[i].xPos -= 2;
}
}
class pillar {
float xPos, opening;
pillar(int i){
xPos = 100 + i * 200;
opening = random(400) + 200;
}
void drawPillar() {
imageMode(CENTER);
image(pillar_up, xPos, opening - 100 - 350, 40, 700);
image(pillar_down, xPos, opening + 100 + 350, 40, 700);
}
}
水管往左跑
水管往左跑
pillar[] p = new pillar[3];
boolean end = false;
boolean intro = true;
int score = 0;
PImage bg, bird, pillar_up, pillar_down;
void setup() {
bg = loadImage("background.jpg");
bird = loadImage("bird.png");
pillar_up = loadImage("pillar_up.png");
pillar_down = loadImage("pillar_down.png");
bg.resize(500, 800);
size(500, 800);
for (int i = 0; i < 3; i++) {
p[i] = new pillar(i);
}
}
void draw() {
background(bg);
for(int i=0;i<3;i++){
p[i].drawPillar();
}
for(int i=0;i<3;i++){
p[i].xPos -= 2;
p[i].checkPosition();
}
}
class pillar {
float xPos, opening;
pillar(int i){
xPos = 100 + i * 200;
opening = random(400) + 100;
}
void drawPillar() {
imageMode(CENTER);
image(pillar_up, xPos, opening - 100 - 350, 40, 700);
image(pillar_down, xPos, opening + 100 + 350, 40, 700);
}
void checkPosition() {
if(xPos < -10){
xPos = xPos + 600;
opening = random(400) + 100;
}
}
}
水管往左跑
pillar[] p = new pillar[3];
bird b = new bird();
boolean end = false;
boolean intro = true;
int score = 0;
PImage bg, bird, pillar_up, pillar_down;
void setup() {
bg = loadImage("background.jpg");
bird = loadImage("bird.png");
pillar_up = loadImage("pillar_up.png");
pillar_down = loadImage("pillar_down.png");
bg.resize(500, 800);
size(500, 800);
for (int i = 0; i < 3; i++) {
p[i] = new pillar(i);
}
}
void draw() {
background(bg);
if(mousePressed || keyPressed){
b.jump();
intro = false;
}
if (end == false) {
b.move();
}
b.drawBird();
if (end == false) {
b.drag();
}
for(int i=0;i<3;i++){
p[i].drawPillar();
}
for(int i=0;i<3;i++){
p[i].xPos -= 2;
p[i].checkPosition();
}
}
class pillar {
float xPos, opening;
pillar(int i){
xPos = 100 + i * 200;
opening = random(400) + 100;
}
void drawPillar() {
imageMode(CENTER);
image(pillar_up, xPos, opening - 100 - 350, 40, 700);
image(pillar_down, xPos, opening + 100 + 350, 40, 700);
}
void checkPosition() {
if(xPos < -10){
xPos = xPos + 600;
opening = random(400) + 100;
}
}
}
class bird {
float xPos, yPos, ySpeed;
bird() {
xPos = 200;
yPos = 400;
}
void drawBird() {
image(bird, xPos, yPos, 60, 60);
}
void jump() {
ySpeed = -10;
}
void drag() {
ySpeed += 0.4;
}
void move() {
yPos += ySpeed;
for (int i = 0; i < 3; i++) {
p[i].xPos -= 3;
}
}
}
碰撞檢測
opening
100 px
100 px
40 px
碰撞檢測
100 px
100 px
40 px
碰撞檢測
100 px
100 px
40 px
碰撞檢測
100 px
100 px
40 px
Safe!
碰撞檢測
100 px
100 px
40 px
碰撞檢測
100 px
100 px
40 px
碰撞檢測
100 px
100 px
40 px
(xPos, yPos)
碰撞檢測
100 px
100 px
40 px
(xPos, yPos)
碰撞檢測
100 px
100 px
40 px
(xPos, yPos)
pillar[i].pos - 20 <= xPos && xPos <= pillar[i].pos + 20
碰撞檢測
100 px
100 px
40 px
(xPos, yPos)
pillar[i].pos - 20 <= xPos && xPos <= pillar[i].pos + 20
yPos <= pillar[i].opening - opening_half_width || yPos >= pillar[i].opening + opening_half_width
碰撞檢測
100 px
100 px
40 px
(xPos, yPos)
if((pillar[i].pos - 20 <= xPos && xPos <= pillar[i].pos + 20) && (yPos < p[i].opening - opening_half_width || yPos > p[i].opening + opening_half_width )){
// collide!
}