class AcGameMenu { constructor(root){ this.root = root; this.$menu = $(`
单人模式

多人模式

设置
`); this.root.$ac_game.append(this.$menu); this.$single_mode = this.$menu.find('.ac-game-menu-field-item-single-mode'); this.$multi_mode = this.$menu.find('.ac-game-menu-field-item-multi-mode'); this.$settings = this.$menu.find('.ac-game-menu-field-item-settings'); this.start(); } start(){ this.add_listening_events(); } add_listening_events(){ let outer = this; this.$single_mode.click(function(){ outer.hide(); outer.root.playground.show(); }); this.$multi_mode.click(function(){ console.log("aaac"); }); this.$settings.click(function(){ console.log("aaa"); }); } show(){ this.$menu.show(); } hide(){ this.$menu.hide(); } } let AC_GAME_OBJECTS = []; class AcGameObject { constructor() { AC_GAME_OBJECTS.push(this); this.has_called_start = false; // 是否执行过start函数 this.timedelta = 0; // 当前帧距离上一帧的时间间隔 } start() { // 只会在第一帧执行一次 } update() { // 每一帧均会执行一次 } on_destroy() { // 在被销毁前执行一次 } destroy() { // 删掉该物体 this.on_destroy(); for (let i = 0; i < AC_GAME_OBJECTS.length; i ++ ) { if (AC_GAME_OBJECTS[i] === this) { AC_GAME_OBJECTS.splice(i, 1); break; } } } } let last_timestamp; let AC_GAME_ANIMATION = function(timestamp) { for (let i = 0; i < AC_GAME_OBJECTS.length; i ++ ) { let obj = AC_GAME_OBJECTS[i]; if (!obj.has_called_start) { obj.start(); obj.has_called_start = true; } else { obj.timedelta = timestamp - last_timestamp; obj.update(); } } last_timestamp = timestamp; requestAnimationFrame(AC_GAME_ANIMATION); } requestAnimationFrame(AC_GAME_ANIMATION); class GameMap extends AcGameObject{ constructor(playground){ super(); this.playground=playground; this.$canvas = $(``); this.ctx = this.$canvas[0].getContext('2d'); this.ctx.canvas.width = this.playground.width; this.ctx.canvas.height = this.playground.height; this.playground.$playground.append(this.$canvas); } start(){ } update(){ this.render(); } render(){ this.ctx.fillStyle = "rgba(0,0,0,0.1)"; this.ctx.fillRect(0,0,this.ctx.canvas.width,this.ctx.canvas.height); } } class Particle extends AcGameObject{ constructor(playground,x,y,radius,vx,vy,color,speed,move_length){ super(); this.playground = playground; this.x = x; this.y = y; this.radius = radius; this.vx= vx; this.vy = vy; this.color = color; this.speed = speed; this.ctx = this.playground.game_map.ctx; this.fraction = 0.9; this.eps = 1; this.move_length = move_length; } start(){ } update(){ if(this.move_length< this.eps||this.speed< this.eps){ this.destroy(); return false; } let moved = Math.min(this.move_length,this.speed*this.timedelta/1000); this.x += this.vx*moved; this.y += this.vy*moved; this.speed *= this.fraction; this.move_length -= moved; this.render(); } render(){ this.ctx.beginPath(); this.ctx.arc(this.x,this.y,this.radius,0,Math.PI * 2,false); this.ctx.fillStyle = this.color; this.ctx.fill(); } } class Player extends AcGameObject { constructor(playground,x,y,radius,color,speed,is_me){ super(); this.playground=playground; this.ctx= this.playground.game_map.ctx; this.x=x; this.y=y; this.vx=0; this.vy=0; this.damage_x = 0; this.damage_y = 0; this.damage_speed = 0; this.move_length = 0; this.radius=radius; this.color=color; this.speed=speed; this.is_me=is_me; this.eps= 0.01; this.cur_skill = null; this.fraction = 0.9; this.spent_time = 0; } add_listening_events() { let outer = this; this.playground.game_map.$canvas.on("contextmenu",function(){ return false; }); this.playground.game_map.$canvas.mousedown(function(e){ const rect = outer.ctx.canvas.getBoundingClientRect(); if(e.which === 3){ outer.move_to(e.clientX - rect.left,e.clientY - rect.top); } else if (e.which === 1){ if ( outer.cur_skill === "fireball" ){ outer.shoot_fireball(e.clientX - rect.left,e.clientY - rect.top); } outer.cur_skill = null; } }); $(window).keydown(function(e){ if(e.which === 81){ outer.cur_skill = "fireball"; return false; } }); } shoot_fireball(tx,ty){ let x =this.x,y=this.y; let radius = this.playground.height * 0.01; let angle = Math.atan2(ty-this.y,tx-this.x); let vx = Math.cos(angle),vy = Math.sin(angle); let color = "orange" let speed = this.playground.height * 1.5; let move_length = this.playground.height * 1; new FireBall(this.playground,this,x,y,radius,vx,vy,"orange",speed,move_length,this.playground.height*0.01); } get_dist(x1,y1,x2,y2){ let dx=x1-x2; let dy=y1-y2; return Math.sqrt(dx*dx+dy*dy); } move_to(tx,ty){ this.move_length= this.get_dist(this.x,this.y,tx,ty); let angle = Math.atan2(ty-this.y,tx-this.x); this.vx=Math.cos(angle); this.vy=Math.sin(angle); } start(){ if(this.is_me){ this.add_listening_events(); } else{ let tx= Math.random() *this.playground.width; let ty = Math.random() *this.playground.height; this.move_to(tx,ty); } } is_attacked(angle,damage){ for(let i = 0;i<10+Math.random()*10;i++){ let x = this.x,y=this.y; let radius = this.radius *Math.random() * 0.1; let angle = Math.PI * 2 *Math.random(); let vx = Math.cos(angle),vy = Math.sin(angle); let color = this.color; let speed = this.speed * 7; let move_length = this.radius *Math.random()*10; new Particle(this.playground,x,y,radius,vx,vy,color,speed,move_length); } this.radius -= damage; if(this.radius<5){ this.destroy(); return false; } this.damage_x = Math.cos(angle); this.damage_y = Math.sin(angle); this.damage_speed = damage *100; this.speed *= 0.9; } update(){ this.spent_time += this.timedelta/1000; if(!this.is_me && this.spent_time > 5 &&Math.random() < 1/180.0){ let player = this.playground.players[Math.floor(Math.random()* this.playground.players.length)]; this.shoot_fireball(player.x,player.y); } if(this.damage_speed>this.eps){ this.vx=this.vy =0; this.move_length= 0; this.x += this.damage_x *this.damage_speed * this.timedelta / 1000; this.y += this.damage_y * this.damage_speed * this.timedelta / 1000; this.damage_speed *=this.fraction; }else{ if(this.move_length`); //this.hide(); this.root.$ac_game.append(this.$playground); this.width= this.$playground.width(); this.height = this.$playground.height(); this.game_map = new GameMap(this); this.players = []; this.players.push(new Player(this,this.width/2,this.height/2,this.height*0.05,"white",this.height*0.15,true)); for (let i = 0; i < 5; i ++ ) { this.players.push(new Player(this, this.width / 2, this.height / 2, this.height * 0.05, this.get_random_color(), this.height * 0.15, false)); } this.start(); } get_random_color(){ let colors = ["blue","red","green","pink","grey"]; return colors[Math.floor(Math.random()*5)]; } start(){ } update(){ } show(){ this.$playground.show(); } hide(){ this.$playground.hide(); } } export class AcGame { constructor(id){ this.id = id; this.$ac_game = $('#'+id); //this.menu = new AcGameMenu(this); this.playground = new AcGamePlayground(this); this.start(); } start() { } }