// ---- The Main script of the task ---- // This script use the Konva library to // use the canvas of HTML5 // ---- Define all elements var width = $("#form").innerWidth(); var height = $("#form").innerWidth(); // stage var stage = new Konva.Stage({ container: 'container', width: width, height: height, }); var my_id = 1; // in practice, every player is player 1 // layer var layer = new Konva.Layer(); var interface_center = [stage.width() / 2, stage.height() / 4 * 2.1]; // table plate // text for debug function writeMessage(message) { text.text(message); } var text = new Konva.Text({ x: 10, y: 10, fontFamily: 'Calibri', fontSize: stage.width() / 30, text: '', fill: 'black', }); stage.add(layer); var player_seat = new Konva.Group({ x: interface_center[0], y: interface_center[1] - stage.width()/3, name: "seat", }); const img_01 = new Image(); const img_02 = new Image(); const img_03 = new Image(); const img_04 = new Image(); img_01.src = '/static/pimgs/image_0001.webp'; img_02.src = '/static/pimgs/image_0002.webp'; img_03.src = '/static/pimgs/image_0003.webp'; img_04.src = '/static/pimgs/image_0004.webp'; image_list = [img_01,img_02,img_03,img_04]; var player_rect = new Konva.Image({ x: 0, y: 0, image: image_list[0], width: stage.width()/6/3, height: stage.width()/6/3, fill:"white", opacity:1, visible: true, stroke: "black", strokeWidth: 0, fillAfterStrokeEnabled: true, }); player_seat.add(player_rect); other_seat_list = new Konva.Group({ x: interface_center[0] - stage.width()/6, y: interface_center[1] - stage.width()/6, }); var other_seat_01 = player_seat.clone(); other_seat_01.find('Image')[0].setAttr('image',image_list[1]); other_seat_01.setAttr('x', 0) .setAttr('y', 0); var other_seat_02 = other_seat_01.clone(); other_seat_02.find('Image')[0].setAttr('image',image_list[2]); other_seat_02.setAttr('x', stage.width()/6); var other_seat_03 = other_seat_01.clone(); other_seat_03.find('Image')[0].setAttr('image',image_list[3]); other_seat_03.setAttr('x', 2*stage.width()/6); other_seat_list.add(other_seat_01) .add(other_seat_02) .add(other_seat_03); //player_seat.find('Image')[0].setAttr('stroke','red'); layer.add(player_seat); layer.add(other_seat_list); self_arrow_list = new Konva.Group({ x: interface_center[0] + stage.width()/6/6, y: interface_center[1] - stage.width()/3 + stage.width()/6/3, }); arrow_01 = new Konva.Arrow({ points:[0,0, -stage.width()/6,stage.width()/6 - stage.width()/6/3 - 3], stroke:'black', fill:'black', pointerLength:stage.width()/6/6/2, pointerWidth:5, strokeWidth:1, shadowColor:'black', visible: false, }) arrow_02 = arrow_01.clone() .setAttr('points',[0,0, 0,stage.width()/6 - stage.width()/6/3 - 3]); arrow_03 = arrow_01.clone() .setAttr('points',[0,0, stage.width()/6 ,stage.width()/6 - stage.width()/6/3 - 3]); self_arrow_list.add(arrow_01).add(arrow_02).add(arrow_03); layer.add(self_arrow_list); sep_line = new Konva.Line({ points:[interface_center[0] - stage.width()/3+stage.width()/6/3,interface_center[1]+stage.width()/6/6, interface_center[0] + stage.width()/3,interface_center[1]+stage.width()/6/6], stroke:'black', strokeWidth:3 }) layer.add(sep_line); function writeMessage(text,message) { text.text(message); } var self_table_hint = player_seat.clone() .setAttr('x',interface_center[0] - stage.width()/6/2.5) .setAttr('y',interface_center[1] - stage.width()/6/4) .setAttr('visible',false); layer.add(self_table_hint); var self_table_text = new Konva.Text({ x: interface_center[0] - stage.width()/3+stage.width()/6/3, y: interface_center[1] - stage.width()/6/6, fontFamily: 'Calibri', fontSize: stage.width() / 30, text: "", fill: 'black', }); layer.add(self_table_text); var other_table_text = self_table_text.clone() .setAttr('y',interface_center[1] + stage.width()/6/4); layer.add(other_table_text); var condition_text = self_table_text.clone() .setAttr('y',interface_center[1] - stage.width()/2.5) layer.add(condition_text); writeMessage(condition_text,'') var explain_text = condition_text.clone() .setAttr('y',interface_center[1] - stage.width()/2.5 - stage.width()/6/1.5) .setAttr('x',interface_center[0] - stage.width()/3) layer.add(explain_text); writeMessage(explain_text,"请点击其他玩家的头像进行选择 \n \n你的头像图片是:") player_example = player_seat.clone() .setAttr('y',interface_center[1] - stage.width()/2.5 - stage.width()/6/3) .setAttr('x',interface_center[0]); layer.add(player_example); send_other = other_seat_list.clone(); send_other.setAttr('y',interface_center[1] + stage.width()/6); layer.add(send_other); receive_other = other_seat_list.clone(); receive_other.setAttr('y',interface_center[1] + 2*stage.width()/6); layer.add(receive_other); for(let i = 0;i<3;i++){ var r = i+3; if(r >= 5) r = r - 4; receive_other.find('Image')[i] .setAttr('image',image_list[r-1]); } other_arrow_list = self_arrow_list.clone() .setAttr('y', interface_center[1] + stage.width()/6 + stage.width()/6/3) .setAttr('visible',true); other_arrow_list.find('Arrow')[0] .setAttr('points',[-stage.width()/6,0, -stage.width()/6,stage.width()/6 - stage.width()/6/3 - 3]); other_arrow_list.find('Arrow')[2] .setAttr('points',[stage.width()/6,0, stage.width()/6,stage.width()/6 - stage.width()/6/3 - 3]); for(let i = 0;i<3;i++){ other_arrow_list.find('Arrow')[i] .setAttr('visible',true); } layer.add(other_arrow_list); other_arrow_list.setAttr('visible',false); send_other.setAttr('visible',false); receive_other.setAttr('visible',false); // ---- Add event var oimg_01 = new Image(); var oimg_02 = new Image(); var oimg_03 = new Image(); oimg_01.src = '/static/pimgs/image_0002.webp'; oimg_02.src = '/static/pimgs/image_0003.webp'; oimg_03.src = '/static/pimgs/image_0004.webp'; other_img_list = [oimg_01,oimg_02,oimg_03]; var t = 1; for(let i = 0;i<3;i++){ other_seat_list.find('.seat')[i].on('mouseover',function(){ other_seat_list.find('Image')[i] .setAttr('shadowBlur',5); self_arrow_list.find('Arrow')[i] .setAttr('visible',true) .setAttr('shadowBlur',5); player_seat.find('Image')[0] .setAttr('shadowBlur',5); writeMessage(self_table_text,"送给玩家"); self_table_hint.find('Image')[0] .setAttr('image',image_list[i+1]); self_table_hint.setAttr('visible',true); }) other_seat_list.find('.seat')[i].on('mouseout',function(){ other_seat_list.find('Image')[i] .setAttr('shadowBlur',0); self_arrow_list.find('Arrow')[i] .setAttr('visible',false) .setAttr('shadowBlur',0); player_seat.find('Image')[0] .setAttr('shadowBlur',0); writeMessage(self_table_text,""); self_table_hint.setAttr('visible',false); }) other_seat_list.find('.seat')[i].on('mousedown',function(){ i_rand = i; if(t % 2 == 1){ while(i_rand == i) i_rand = [0,1,2].at(Math.floor(Math.random() * 3)); } other_seat_list.find('Image')[i] .setAttr('shadowBlur',0) .setAttr('strokeWidth',5); player_seat.find('Image')[0] .setAttr('shadowBlur',5) .setAttr('strokeWidth',5); self_arrow_list.find('Arrow')[i] .setAttr('shadowBlur',0) other_seat_list.setAttr('listening',false); writeMessage(self_table_text,"随机中..."); setTimeout(() => { player_seat.find('Image')[0] .setAttr('shadowBlur',5) .setAttr('strokeWidth',5) .setAttr('stroke','red'); other_seat_list.find('Image')[i_rand] .setAttr('shadowBlur',5) .setAttr('stroke','red'); self_arrow_list.find('Arrow')[i_rand] .setAttr('shadowBlur',5) .setAttr('fill','red') .setAttr('stroke','red'); if(i != i_rand){ other_seat_list.find('Image')[i_rand] .setAttr('stroke','red') .setAttr('strokeWidth',5) .setAttr('shadowBlur',5); self_arrow_list.find('Arrow')[i_rand] .setAttr('stroke','red') .setAttr('fill','red') .setAttr('visible',true) .setAttr('shadowBlur',5); } writeMessage(self_table_text,"你最终送给了"); writeMessage(other_table_text,"请等待其他人进行选择..."); other_seat_list.setAttr('listening',false); self_table_hint.find('Image')[0] .setAttr('image',other_img_list[i_rand]); self_table_hint.setAttr('visible',true); setTimeout(() =>{ player_example.setAttr('visible',false); writeMessage(other_table_text,"随机后,其他玩家送给:"); other_arrow_list.setAttr('visible',true); send_other.setAttr('visible',true); receive_other.setAttr('visible',true); next_round_button.setAttr('visible',true); writeMessage(explain_text,"在这个回合中,你送给了和你选择不同的玩家。\n\n请点击“继续”再进行一次选择。 \n\n请点击“开始”,开始练习。") },1500) }, 500); }) } var next_round_button= new Konva.Label({ x: interface_center[0] + stage.width()/3, y: interface_center[1] - stage.width()/6/6, opacity: 0.75, visible: false, }); layer.add(next_round_button); next_round_button.add(new Konva.Tag({ fill: 'black', lineJoin: 'round', cornerRadius: 5, shadowColor: 'black', shadowBlur: 0, shadowOffset: 0, shadowOpacity: 0.75 })); next_round_button.add(new Konva.Text({ text: '继续', fontFamily: 'Calibri', fontSize: stage.width()/30, padding: 5, fill: 'white' })); next_round_button.on('mouseout', function() { next_round_button.setAttr('opacity', 0.75); }) next_round_button.on('mouseover', function() { next_round_button.setAttr('opacity', 1); }) next_round_button.on('mousedown', function() { location.reload(); }) function liveRecv(data) { switch (data.msg_type) { case 'control': switch (data.msg) { case 'practice': my_id = data.player_id; writeMessage(my_id); break; } } } // ---- Run game_ready = 'Ready!'; document.addEventListener("DOMContentLoaded", (event) => {});