Flash – Action Script 3 กับตำแหน่งและการเคลื่อนที่ของวัตถุขั้นพื้นฐาน

30/07/2013

พื้นฐานการสร้างนาฬิกาด้วย Flash

18/08/2013

Flash – Action Script 3.0 กับวันและเวลา

15/08/2013
empty image
empty image

ตัวนับเวลา (Timer)

คลาส Timer เป็นตัวนับเวลา นี่เป็นพื้นฐานจริงๆ สำหรับผู้เริ่มต้น
Methods ของคลาส Timer มี

1. Timer(Delay:Number, repeatCount:int)
ใช้ตั้งเวลานั่นเอง โดย
Delay คือค่าหน่วงเวลาคือใช้เวลาเท่าไหร่ในการเดิน 1 ครั้งหรือรอบ ถ้าค่าหน่วงเป็น 100 ก็จะเป็น 0.1 วินาทีต่อรอบการเดิน ดังนั้นถ้าจะให้เดินเป็นวินาทีเลยต้องกำหนดค่าหน่วงเวลาเป็น 1000
repeatCount คือรอบหรือจำนวนครั้งในการเดิน

2. reset()
ล้างเวลาที่ตั้ง

3. start()
เริ่มนับเวลา

4. stop()
หยุดเวลา

มีเหตุการณ์ (Event) คือ
timer – เมื่อเวลาเดิน ตามที่กำหนดไว้ในค่าหน่วง (Delay)
timerComplete – เมื่อเวลาเดินครบรอบที่กำหนดใน จำนวนรอบ (repeatCount)

คุณสมบัติ Properties คือ

1. constructor : Object – อันนี้ไม่รู้หง่ะ -..-
2. currentCount : int – เวลาที่นับอยู่ ณ ปัจจุบัน
3. delay : Number – ค่าหน่วงเวลา
4. repeatCount : int – จำนวนรอบ
5. running: Boolean – สถานะของเวลา ถ้าเดินอยู่จะคืนค่า true นอกนั้นก็ false

วิธีใช้ทดลองนับเวลาโดยพิมพ์โค้ดลงในแถบ Action (คลิกที่เฟรมแรก กด [F9])

mytime:Timer = new Timer(1000, 10) //ตั้งเวลาแล้ว 10 รอบ รอบละ 1 วิ
mytime.start(); //สั่งให้เวลาเดิน

เวลาเดินแล้วไปเรื่อยๆ จนครบ 10 ครั้งหรือรอบ แต่ไม่มีอะไรเกิดขึ้น ก็เพราะเราไม่ได้สร้างอะไรเพื่อฟังเหตุการณ์นี้
คราวนี้ลองเพิ่มฟังก์ชันเพื่อทำอะไรซักอย่าง

var mytime:Timer = new Timer(1000,10);//ตั้งเวลา
mytime.addEventListener(TimerEvent.TIMER, start_time);//ฟังเหตุการณ์เมื่อเวลาเดินให้ไปทำ start_time
mytime.start();// เริ่มนับเวลา
function start_time(evt:TimerEvent):void{
    trace("hello");//พิมพ์ข้อความ hello ออกทาง output
}

เมื่อเกิดเหตุกาณ์ขึ้นกับเวลา(เวลาเดิน) ในที่นี้คือ ทุกครั้งที่เวลาเดินทุกๆ 1 วินาที จะทำฟังก์ชัน start_time ซึ่งก็คือ พิมพ์ hello เมื่อลองทดสอบดู จะเห็นว่ามันพิมพ์ hello จำนวน 10 ครั้ง พอเข้าใจแล้วใช่มั้ย…

หยุดเวลากลางคันด้วย stop()

var mytime:Timer = new Timer(1000,10);

mytime.addEventListener(TimerEvent.TIMER, timestart);
mytime.start();
function timestart(evt:TimerEvent):void{
    trace("hello");
    mytime.stop();
}

เมื่อลดรัน จะเห็นว่า hello นั้น แสดงมาแค่ 1 ครั้ง นั่นก็เพราะเราสั่ง stop ไปนั่นเอง…

ฟังก์ชันอื่นๆ ที่เกี่ยวกับเวลา
getTimer()
เมื่อรันไฟล์ สามารถใช้ getTimer() ตรวจสอบเวลา ซึ่งจะคืนค่าเป็นเวลาปัจจุบันที่ไฟล์รันผ่านมา ซึ่งเป็นเลข 4 หลัก โดยหน่วยเวลาจะเป็น มิลลิวินาที
เอาแค่นี้แหละ… ที่เหลือไปดูเพิ่มเติมใน help.adobe.com

แปลงตัวเลขเป็นเข็ม
ไม่รู้จะตั้งหัวข้อว่าไร -.- คือถ้าเราจะเปลี่ยนจากตัวเลขให้เป็นการเดินแบบเข็ม
สมมติว่าเราจะทำให้เข็มเดินเป็นวงกลมนะ ซึ่งมี 360 องศา เป็น 60 วินาที แสดงว่า 1 วินาทีเนี่ย มันจะเดินครั้งละ 6 องศา 60 วินาทีก็ 360 องศา แล้วไงต่อ เราก็หมุนวัตถุไป 6 องศาไง โดยใช้คุณสมบัติ rotation ไปดูโค้ดและตัวอย่างกันเลย…

Download file: https://www.dropbox.com/s/snol6qcodfpbs3e/timer.fla
โค้ด…

txtCount_out.text="0";
var timeCount:Timer=new Timer(1000);
timeCount.addEventListener(TimerEvent.TIMER, counter);
btn_start.addEventListener(MouseEvent.CLICK, startcount);
btn_stop.addEventListener(MouseEvent.CLICK, stopcount);
btn_clear.addEventListener(MouseEvent.CLICK, clearcount);
function counter(evt:TimerEvent):void {
txtCount_out.text=String(timeCount.currentCount);
sechand.rotation+=6//หมุนเข็มไป 6 องศา
}
function startcount(evt:MouseEvent):void {
timeCount.start();
}
function stopcount(evt:MouseEvent):void {
timeCount.stop();
}
function clearcount(evt:MouseEvent):void {
timeCount.reset();
txtCount_out.text="0";
sechand.rotation=0;//ย้ายเข็มมาอยู่ 0 องศา หรือชี้ที่เลข 12 ประมาณนั้น
}

นับเวลาถอยหลัง

โดยเรากำหนดเวลาเริ่มต้นก่อน แล้วเวลานับถอยหลังไปเรื่อยๆ จนครบเวลาที่กำหนด

var Count:int = 10;//กำหนดเวลาที่จะนับถอยหลัง
var timer:Timer = new Timer(1000, Count);
timer.start();
timer.addEventListener(TimerEvent.TIMER, start_count);
function start_count(e:TimerEvent):void
{
trace(Count);
Count–;//เวลาจะลดลงทุกๆ 1 วินาที
}

แต่มันมีข้อผิดพลาดเล็กน้อย เนื่องจาก Timer มันจะนับรอบตามที่เรากำหนด จากข้างบนคือ 10 รอบ คือนับ 10 9 8 7 6 5 4 3 2 1 มันสิ้นสุดแค่ 1 คือนับ 10 รอบเท่านั้น เราจึงต้องใช้คุณสมบัติ currentCount เข้ามาช่วยโดยเวลาเต็มลบด้วยเวลาที่นับไปแล้ว ซึ่งถ้าเวลาเต็ม 10 นับไปแล้ว 10 ลบกันมันก็จะเหลือ 0
ลองดูตัวอย่างกันเลย

var Count:int = 10;//กำหนดเวลาที่จะนับถอยหลัง
var timer:Timer = new Timer(1000, Count);
timer.start();
timer.addEventListener(TimerEvent.TIMER, start_count);
function start_count(e:TimerEvent):void
{
trace(Count-timer.currentCount);//เอาเวลาเต็มลบด้วยเวลาที่นับไปแล้วก็จะได้เวลาที่เหลือ
}

เมื่อทดสอบดู มันจะเริ่มนับที่ 9 มาจนถึง 0 ซึ่งก็คือนับ 10 รอบเหมือนกัน ซึ่งจริงๆ มันควรจะเป็นแบบนี้ใช่ป่ะ ? คือตอนนี้ยังงงอยู่ว่า แบบไหนมันนับถูก ฮ่าๆๆ
อืม..
– สมมติเราจะนับถอยหลัง 1 ถึง 3 เราเริ่มที่ 1 พอนับไป 1, 2, 3 ก็จะเป็นการนับ 3 ครั้ง ดังนั้นการนับครั้งที่ 4 ซึ่งก็คือ 4 ก็จะเป็นหมดเวลา หรือ นับ 4 = ครั้งที่ 4=หมดเวลา
– สมมติเราจะนับ 1 ถึง 3 แต่เราเริ่มที่ 0 พอนับไป 0, 1, 2 ก็จะเป็นการนับ 3 ครั้ง ดังนั้นการนับครั้งที่ 4 ซึ่งก็คือ 3 ก็จะหมดเวลา หรือ นับ 3 = ครั้งที่ 4= หมดเวลา

มันก็ประมาณนี้แหละ แต่อันล่างน่าจะถูก เฮ้ย งงหว่ะ เรื่องง่ายๆ แต่งง ฮ่าๆๆ
ลองดูตัวอย่างนี้เลยละกัน

โค้ดพร้อมอธิบาย

//กำหนดตัวแปรต่างๆ
var Count:int;
var timer:Timer=new Timer(1000);
var hour:Number;
var min:Number;
var min_mod:Number;
var sec:Number;
var str_time:String;
btn_stop.visible=false;//ซ่อนปุ่มหยุดไว้ก่อน
mc_timeout.gotoAndStop(1);//เล่นmc หมดเวลา แต่เล่นและหยุดอยุ่แค่เฟรมแรกนะ
Input_count.text="10";//กำหนดค่าเริ่มต้นของกล่องรับค่า
Input_count.addEventListener(Event.CHANGE, change_timer);//ฟังถ้ากล่องรับค่ามีการเปลี่ยนค่า

function change_timer(evt:Event):void {//ฟังก์ชันถ้ามีการเปลี่ยนแปลงข้อความ
Count=int(Input_count.text);//รับค่าเข้ามาใส่ไว้ในตัวแปล count
hour=Math.floor(Count/3600);//เอาเวลาที่รับเข้ามาหารด้วย 3600 เอาแต่จำนวนเต็มก็จะเป็น ชม.
min_mod=Count%3600;//หารเอาเศษวินาทีที่เหลือจาก ชม.
min=Math.floor(min_mod/60);//เอาเศษวินาทีที่เหลือมาหารด้วย 60 เพื่อแปลงเป็นนาที
sec=min_mod%60;//ส่วนวินาทีที่เหลือก็จะเป็นค่าของ sec หรือวินาทีนั่นแหละ
Time_count.text=String(hour+":"+min+":"+sec);//พิมพ์ค่าออก
}
btn_start.addEventListener(MouseEvent.CLICK, start_count);//รอฟังการกดปุ่มเริ่ม
function start_count(evt:MouseEvent) {
Count=int(Input_count.text);//กำหนดค่าให้ count เท่ากับค่าที่รับเข้ามาทาง input
timer.repeatCount=Count;//กำหนดรอบของการนับเท่ากับค่าที่รับเข้ามา
timer.start();//เริ่มนับเวลา
btn_start.visible=false;//ซ่อนปุ่มหยุด
btn_stop.visible=true;//ซ่อนปุ่มเริ่ม
}

timer.addEventListener(TimerEvent.TIMER, time_count);//เมื่อเวลาเริ่มนับ
function time_count(e:TimerEvent):void {
var TotalCount:Number;
TotalCount=Count-timer.currentCount;//อันนี้กำหนดเพิ่มาเฉยๆอ่ะ ถ้าเอาไปใช้เลยมันยาว 555+
hour=Math.floor(TotalCount/3600);//เอาเวลาที่รับเข้ามาหารด้วย 3600 เอาแต่จำนวนเต็มก็จะเป็น ชม.
min_mod = TotalCount%3600;//หารเอาเศษวินาทีที่เหลือจาก ชม.
min = Math.floor(min_mod/60);//เอาเศษวินาทีที่เหลือมาหารด้วย 60 เพื่อแปลงเป็นนาที
sec = min_mod%60;//ส่วนวินาทีที่เหลือก็จะเป็นค่าของ sec หรือวินาทีนั่นแหละ
str_time=String(hour+":"+min+":"+sec);//ส่งออกค่าเวลาที่นับ
Time_count.text=str_time;//เอาเวลาเต็มลบด้วยเวลาที่นับไปแล้ว
if(hour==0&&min==0&&sec==0){
mc_timeout.gotoAndPlay(1);
}
}

btn_stop.addEventListener(MouseEvent.CLICK, stop_count);//ฟังถ้ากดหยุด
function stop_count(evt:MouseEvent):void{
timer.stop();//หยุดตัวนับ
btn_stop.visible=false;//ซ่อนปุ่มหยุด
btn_start.visible=true;//โชว์ปุ่มเริ่ม
}

btn_reset.addEventListener(MouseEvent.CLICK, reset_count);//ฟังเมื่อกดปุ่มรีเซต
function reset_count(evt:MouseEvent):void {
timer.reset();//รีเซตเวลา
Time_count.text="0:0:0";//กำหนดค่าใหม่ให้เป็น 0
btn_start.visible=true;//โชว์ปุ่มเริ่ม
btn_stop.visible=false;//ซ่อนปุ่มหยุด
mc_timeout.gotoAndStop(1);//หยุด mc หมดเวลาไว้ก่อน
}

โหลดไฟล์ : https://www.dropbox.com/s/h1nr05gxhwlalp6/time_countdown.fla

จบแล้วกับเวลาที่ใช้เป็นตัวนับ ต่อไปพูดถึงเวลาที่ใช้ในชีวิตจริงกันมั่ง ซึ่งมันอยู่ในคลาส Date…

วันเวลา (Date)

คลาส Date เป็นคลาสที่เกี่ยวข้องกับวันและเวลาจริงๆ ซึ่งจะดึงมาจากเครื่องที่ทำการรันไฟล์นั้นๆ 
คุณสมบัติ (Properties) ที่จำเป็น

date : Number – วันเดือน เป็นตัวเลข 1 ถึง 31
day : Number – วันในสัปห์ดา เป็นตัวเลข 0 คือวันอาทิตย์, 1 คือวันจันทร์ ไปเรื่อย…
dayUTC : Number – เหมือนข้างบน
fullYear : Number – เลขปี 4 ตัว เช่น 2013
hours : Number – ชั่วโมง เป็นตัวเลข 0 – 23
milliseconds : Number – มิลลิวินาที เป็นตัวเลข 0 ถึง 999
minutes : Number – นาที เป็นตัวเลข 0 ถึง 59
month : Number – เดือน เป็นตัวเลข 0 คือมกราคม ไปเรื่อยๆ…
seconds : Number – วินาทีเป็นตัวเลข 0 ถึง 59

และมีเมธอด (Methods) 
Date(yearOrTimevalue:Object, month:Number, date:Number = 1, hour:Number = 0, minute:Number = 0, second:Number = 0, millisecond:Number = 0)

Date(ปี, เดือน, วัน, ชั่วโมง, นาที, วินาที, มิลลิวินาที)
เป็นข้อมูลเวลา มีวัน เดือน ปี เวลาชั่วโมง นาที วินาที เขตเวลา

และยังมีเมธอทอื่นๆอีกเยอะลองไปส่องดูเองเน้อ เดี๋ยวมันจะยาวไป -..-
ดูทั้งหมดได้ที่ …help.adobe.com

มาลองกันเลย พิมพ์โค้ด…

var now:Date = new Date();
trace(now);// แสดงทั้งวันและเวลา และ time zone
trace(now.toDateString()); // แสดงแค่วันเดือนปีเท่านั้น

เมื่อ test movie สังเกตุตรง output จะแสดงเป็น…

Thu Aug 15 18:13:54 GMT+0700 2013
Thu Aug 15 2013

ซึ่งมันเป็นรูปแบบที่มันกำหนดมาให้ ถ้าเราจะเปลี่ยนหล่ะ ? ก็ใช้คุณสมบัติของ Date ในการแสดงเฉพาะตัวใดตัวหนึ่ง ตัวอย่าง จะมาแสดงแค่ ตัวเลขวัน-เดือน-ปี

var now:Date = new Date();
var date:Number=now.date;
var month:Number=now.month+1;
var year:Number=now.fullYear;
trace(day+"-"+month+"-"+year);

บรรทัด 1: สร้างตัวแปล now ชนิด Date
บรรทัด 2: ตัวแปล date โดยมีค่าเป็นตัวเลขวัน
บรรทัด 3: ตัวแปล month โดยมีค่าเป็นตัวเลขเดือน (ที่ +1 เพราะเดือนมกราคามันเริ่มด้วย 0 เลยต้อง)
บรรทัด 4: ตัวแปล year โดยมีค่าเป็นตัวเลขปี ค.ศ.
บรรทัด 5: พิมพ์ค่าออกมาโดยคั่นด้วย –

มาดูที่เวลากันบ้าง ก็เหมือนกันแหละนะ ใช้คุณสมบัติของ Date แสดงเฉพาะเวลา

var now:Date = new Date();
var hh:Number=now.hours;
var mm:Number=now.minutes;
var ss:Number=now.seconds;
trace(hh+"-"+mm+"-"+ss);

ก็คงไม่ต้องอธิบายอะไร
แต่จะเห็นว่า ทำไมเวลาวินาทีมันไม่เดิน….ก็เพราะเราสั่งพิมพ์ค่าเวลา แค่นั้น จบ.. ถ้าจะพิมพ์ค่าเวลาตลอด ต้องใช้ Timer มาช่วย หรือจะใช้เหตุการณ์ Enter Frame ก็ได้

ใช้ Timer

var timer:Timer= new Timer(100);
timer.start();
timer.addEventListener(TimerEvent.TIMER, start_time)
function start_time(evt:Event):void{
var now:Date = new Date();
var hh:Number=now.hours;
var mm:Number=now.minutes;
var ss:Number=now.seconds;
txt_showtime.text=hh+"-"+mm+"-"+ss;
}

ใช้เหตุการณ์ Enter Frame

stage.addEventListener(Event.ENTER_FRAME, start_time)
function start_time(evt:Event):void{
var now:Date = new Date();
var hh:Number=now.hours;
var mm:Number=now.minutes;
var ss:Number=now.seconds;
txt_showtime.text=hh+"-"+mm+"-"+ss;
}

กำหนดเวลาเอง

กำหนดเพื่อเอาไว้ใช้ทำอะไรซักอย่าง ก็แล้วแต่ เช่นนับถอยหลังไรงี้
โดยรูปแบบก็คือ Date(ปี, เดือน, วัน, ชั่วโมง, นาที, วินาที, มิลลิวินาที)
ตัวอย่างนับวันเกิดละกัน สมมติเกิดวันที่ 31 มกราคม 2540 ส่วนเวลาไม่ใส่ละกัน

var now:Date = new Date();
var now_date:Number=now.date;
var now_month:Number=now.month+1;
var now_year:Number=now.fullYear;
var birthdate:Date=new Date(1997,1,31); //กำหนดวันเกิดตรงนี้
var bd_date:Number=birthdate.date;
var bd_month:Number=birthdate.month;
var bd_year:Number=birthdate.fullYear;
var yourage:Number=now_year-bd_year;
if (now_month < bd_month || (now_month == bd_month && now_date < bd_date)) {
}
trace("คุณอายุ : "+yourage+" ปี");

เอิ่ม….คือก็เอาปีปัจจุบัน ลบ ปีเกิด หรือ 2013-1997 = 16
ตรงบรรทัดที่ 10 เช็คว่าวันและเดือนปัจจุบันเกินวันเกิดไปยัง ถ้ายัง ต้องเอาปีลบออก 1

การแปลงเวลาให้เป็นรูปแบบของไทย เขียนไว้อีกบทความนะ ตรงนี้ยาวไป ฮ่าๆๆ
พอแล้วหล่ะมั้ง วันกับเวลา ทิ้งท้ายด้วยนาฬากาส่งท้าย… เดี๋ยวค่อยอธิบายทีหลัง ฮ่าๆ

ปล. ผมยังไม่เข้าใจความต่างระหว่างใช้ Properties กับใช้ Methods ในการแสดงค่า เช่นจะดึงค่าชั่วโมงของโค้ดข้างบน สามารถใช้คุณสมบัติ now.hours หรือจะใช้เมธอท now.getHours() ก็ได้เหมือนกัน งง ใครรู้บอกที ฮ่าๆ Zzz

Ref.
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/Date.html
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/utils/Timer.html