茶會成發

建資網管 賴昱錡

-

三四個很水的專案

動機

  • 想學javascript、想學架網頁、
    想學python,也想水過成發
  • 其實本來想做中文情感分析,
    可是來不及學jieba跟bert

我是誰

  • 建資網管
  • 跟雅思8分普天同慶、智慧鐵人賽破台
    明年資奧&地奧國手brine大電神同班,
    被揍爛 ; - ;

打地鼠

whack-a-mole

demo: here

<div class="content">
  <div class="row">
    <img src="yellow.png" class="cell" title="yellow"/>
  </div>
  <div class="row">
    <img src="yellow.png" class="cell" title="yellow"/>
  </div>
  <div class="row">
    <img src="yellow.png" class="cell" title="yellow"/>
  </div>
  <div class="control">
    <div class="msg">
      <span id="time">剩餘時間:0s</span>
      <button>遊戲開始</button>
      <span id="combo">成績分數:0</span>
    </div>
    <hr />
    <b>遊戲說明</b>
    <p>打地鼠遊戲,請點擊紅色圖片獲得分數(滿分 100)</p>
    <hr />
  </div>
</div>

HTML 

body{
  margin:0;
  display: flex;
  justify-content: center;
  height:100vh;
  text-align: center;
}
.content{
  display:flex;
  flex-flow: column nowrap;
  align-items: center;
  justify-content: center;
}
.cell{
  background: yellow;
  border:5px solid #6bd1eb;
  cursor: pointer;
  width:100px;
  height:100px;
}
.control{
  max-width:350px;
}
.msg{
  margin:5px auto;
  display: flex;
  justify-content: space-around;
  line-height: 2rem;
}
button,span{
  width:33%;
}

CSS

//初始化
var btn=document.getElementsByTagName("button")[0]; //button
var time=document.getElementById("time"); //find time
var combo=document.getElementById("combo"); //find score
var animal=document.getElementsByClassName("cell");
var flag=0; //game over?
var sec=0,count=0;
var beYellow=new Array(); //到時候會存放所有 red 事件的轉黃定時器,陣列有 100 個位置
btn.addEventListener("click",gamestart); //規劃點選動作

初始化

function gamestart(){ 
  sec=60,count=0,flag=1;
  time.textContent=`剩餘時間:${sec}`;
  combo.textContent=`成績分數:${count}`;
  btn.removeEventListener("click",gamestart); 

  let start=setInterval(()=>{ 
    if(sec==0){
      clearInterval(start);
      flag=0;
      btn.addEventListener("click",gamestart);
    }
    else{
      sec--;
      time.textContent=`剩餘時間:${sec}`;
    }
  },1000);
  
  for(let i=0;i<100;i++){ 
    let ontime=Math.floor(Math.random()*57000); 
    let which=Math.floor(Math.random()*9);  
    let delay=Math.floor(Math.random()*3)+2; 

    setTimeout(function(){
      showit(which,delay,i);
    },ontime);
  }
}

遊戲開始

function showit(siWhich,siDelay,siId){ 
  if(animal[siWhich].title!="yellow"){ 
    let next=(siWhich+1)%9;
    let next=Math.floor(Math.random()*9);  

    setTimeout(function(){
      showit(next,siDelay,siId);
    },100);
  }
  else{ 
    animal[siWhich].src="red.png";
    animal[siWhich].style.background="red";
    animal[siWhich].title="red";
    animal[siWhich].alt=siId;

    beYellow[siId]=setTimeout(() => { 
      animal[siWhich].src="yellow.png";
      animal[siWhich].style.background=null;
      animal[siWhich].title="yellow";
      animal[siWhich].alt=null;
    }, siDelay*1000);
  }
}

燈號的觸發處理

document.onkeydown=keyboard;
function keyboard(){
  if(flag){
    switch (event.keyCode) {
      case 103: getcount(0);break;
      case 104: getcount(1);break;
      case 105: getcount(2);break;
      case 100: getcount(3);break;
      case 101: getcount(4);break;
      case 102: getcount(5);break;
      case 97: getcount(6);break;
      case 98: getcount(7);break;
      case 99: getcount(8);break;
    }
  }
}

keyboard processing

function getcount(who) { 
  if(animal[who].title=="red"){ 
    animal[who].src="green.png";
    animal[who].style.background="green";
    animal[who].title="green";

    count++;
    combo.textContent=`Score:${count}`;

    id=animal[who].alt; 
    clearTimeout(beYellow[id]); 
    animal[who].alt=null;

    setTimeout(() => { 
      animal[who].src="yellow.png";
      animal[who].style.background=null;
      animal[who].title="yellow";
    }, 1000);
  }
}

Score

node.js

discord music bot

discord.js

ffmpeg

Record, convert and stream audio and video.

opus encoder

download yt video

const { Client } = require('discord.js');
const ytdl = require('ytdl-core');
const { token } = require('./token.json');
const { prefix } = require('./config.json');
const client = new Client();

class Music {

    constructor() {
        this.queue = {};

        this.connection = {};

        this.dispatcher = {};
    }

    async join(msg) {
        if (msg.member.voice.channel !== null) {
            this.connection[msg.guild.id] = await msg.member.voice.channel.join();
        } else {
            msg.channel.send('Please join a voice channel.');
        }

    }

    async play(msg) {

        const guildID = msg.guild.id;

        if (!this.connection[guildID]) {
            msg.channel.send('請先將機器人 `!!join` 加入頻道');
            return;
        }

        if (this.connection[guildID].status === 4) {
            msg.channel.send('請先將機器人 `!!join` 重新加入頻道');
            return;
        }

        const musicURL = msg.content.replace(`${prefix}play`, '').trim();

        try {

            const res = await ytdl.getInfo(musicURL);
            const info = res.videoDetails;

            if (!this.queue[guildID]) {
                this.queue[guildID] = [];
            }

            this.queue[guildID].push({
                name: info.title,
                url: musicURL
            });

            if (this.isPlaying[guildID]) {
                msg.channel.send(`歌曲加入隊列:${info.title}`);
            } else {
                this.isPlaying[guildID] = true;
                this.playMusic(msg, guildID, this.queue[guildID][0]);
            }

        } catch(e) {
            console.log(e);
        }

    }

    playMusic(msg, guildID, musicInfo) {

        msg.channel.send(`播放音樂:${musicInfo.name}`);

        this.dispatcher[guildID] = this.connection[guildID].play(ytdl(musicInfo.url, { filter: 'audioonly' }));
        
        this.dispatcher[guildID].setVolume(0.5);

        this.queue[guildID].shift();

        this.dispatcher[guildID].on('finish', () => {

            if (this.queue[guildID].length > 0) {
                this.playMusic(msg, guildID, this.queue[guildID][0]);
            } else {
                this.isPlaying[guildID] = false;
                msg.channel.send('目前沒有音樂了,請加入音樂 :D');
            }

        });

    }

    resume(msg) {

        if (this.dispatcher[msg.guild.id]) {
            msg.channel.send('恢復播放');

            
            this.dispatcher[msg.guild.id].resume();
        }

    }

    pause(msg) {

        if (this.dispatcher[msg.guild.id]) {
            msg.channel.send('暫停播放');

            
            this.dispatcher[msg.guild.id].pause();
        }

    }

    skip(msg) {

        if (this.dispatcher[msg.guild.id]) {
            msg.channel.send('跳過目前歌曲');

           
            this.dispatcher[msg.guild.id].end();
        }

    }

    nowQueue(msg) {

        
        if (this.queue[msg.guild.id] && this.queue[msg.guild.id].length > 0) {
           
            const queueString = this.queue[msg.guild.id].map((item, index) => `[${index+1}] ${item.name}`).join();
            msg.channel.send(queueString);
        } else {
            msg.channel.send('目前隊列中沒有歌曲');
        }

    }

    leave(msg) {

       
        if (this.connection[msg.guild.id] && this.connection[msg.guild.id].status === 0) {

            
            if (this.queue.hasOwnProperty(msg.guild.id)) {

               
                delete this.queue[msg.guild.id];

                
                this.isPlaying[msg.guild.id] = false;
            }

           
            this.connection[msg.guild.id].disconnect();
        } else {
            msg.channel.send('機器人未加入任何頻道');
        }

    }
}

const music = new Music();

client.on('message', async (msg) => {

    if (!msg.guild) return;


    if (msg.content === `${prefix}join`) {

        // 機器人加入語音頻道
        music.join(msg);
    }

    if (msg.content.indexOf(`${prefix}play`) > -1) {

        // 如果使用者在語音頻道中
        if (msg.member.voice.channel) {

            // 播放音樂
            await music.play(msg);
        } else {

            // 如果使用者不在任何一個語音頻道
            msg.reply('你必須先加入語音頻道');
        }
    }

    if (msg.content === `${prefix}resume`) {

        // 恢復音樂
        music.resume(msg);
    }

    if (msg.content === `${prefix}pause`) {

        music.pause(msg);
    }


    if (msg.content === `${prefix}skip`) {

        music.skip(msg);
    }

    if (msg.content === `${prefix}queue`) {
        
        music.nowQueue(msg);
    }

    if (msg.content === `${prefix}leave`) {

        music.leave(msg);
    }
});

client.on('ready', () => {
    console.log(`Logged in as ${client.user.tag}!`);
});

client.login(token);

code

Hexo blog

what's that?

demo:

https://expectlai.github.io/

  • Blazing fast
  • Simple deployment method
  • markdown support
  • Support many plugins.
  • support mathjax, katex.
  • Elegant! Very elegant!
{# Blogroll #}
{% if theme.recent_posts %}
<div class="links-of-blogroll motion-element {{ "links-of-blogroll-" + theme.recent_posts_layout  }}">
<br>
<div class="links-of-blogroll-title">
    <!-- 設定你要的fa fa icon-->
    <i class="fa fa-history fa-{{ theme.recent_posts_icon | lower }}" aria-hidden="true"></i>
    {{ theme.recent_posts_title }}
</div>
<ul class="links-of-blogroll-list">
    <!--{% set posts = site.posts.sort('-date') %}-->
    {% set posts = site.posts.sort('-date').toArray() %}
    {% for post in posts.slice('0', '5') %}
    <li class='pull-left' style="white-space:normal; text-align:left" >
      <time title="{{ __('post.created') }}" itemprop="dateCreated datePublished" datetime="{{ moment(post.date).format() }}">
        {{ date(post.date, 'MM/DD') }}
      </time>
      <a href="{{ url_for(post.path) }}" title="{{ post.title }}">{{ post.title }}</a>
      <br>
    </li>
    {% endfor %}
</ul>
</div>
{% endif %}

add recent posts to sidebar

// sidebar.njk

gitalk:
  enable: true
  github_id:  # GitHub 作者帳號
  repo: richardlaiiiii.github.io # 你的 Repo 名稱,通常就是網域
  client_id: xxxxxxxx # 剛剛申請的 Client ID
  client_secret: xxxxxxxx # 剛剛申請的 Client Secret
  admin_user: hsiangfeng # 管理者的帳號
  distraction_free_mode: true # 無干擾模式
  language: zh-TW ## 語系

Github-gitalk

Some CSS (?

//bg custom image
body {
    background:url(/images/bg.jpg); 
    background-repeat: no-repeat; 
    background-attachment:fixed; 
    background-size: cover; 
    background-position:50% 50%; 
}
// link style
.post-body p a{
  color: #00c3ff; 
  border-bottom: none;
  border-bottom: 1px solid #00c3ff;
  &:hover {
    color: #0044ff; //游標移到上方時
    border-bottom: none;
    border-bottom: 1px solid #0044ff;
  }
}

Discord.py

比discord.js好實作很多的東西

可能很水 但比較少人在弄 (? 的功能

using googletrans

pixiv.cat api

@bot.command()
async def pix(ctx, *,args):
    msg = str(args)
    res = requests.get(f'https://pixiv.cat/{msg[-8:]}.jpg')
    if int(res.status_code) == 200:
        await ctx.send(f'https://pixiv.cat/{msg[-8:]}.jpg')
    elif int(res.status_code) == 404:
        x = 1
        while int(requests.get(f'https://pixiv.cat/{msg[-8:]}-{x}.jpg').status_code) == 200:
            await ctx.send(f'https://pixiv.cat/{msg[-8:]}-{x}.jpg')
            x+=1
@bot.command()
async def translate(ctx, *,args):
    translator = Translator()
    r=args.split(' ',1)
    translation = translator.translate(str(r[1]), dest=str(r[0]))
    s=str(translation.text)
    s=s.capitalize()
    await ctx.send(s)

Some games

耍笨紀實

  • 不會讀json檔
  • 不會檢查型別
  • YTP燒雞
Made with Slides.com