There was nothing to do, here is my sheet. I do not pretend to write a sample, but I hope I will convey the general ideas.
Also, signatures will be later
Wrote under chrome
PSS finish up to 18, hehe
String.prototype.noPx = function(){//решил написать функцию, которая поможет избавиться от мерзких `px` //впрочем, вышло все равно костыльно, переделывать - лень var str = this.toString(); if(str.substr(-2,2) === 'px'){ return str.substr(0,str.length-2)*1; } return 0; } var Target = function(){//создаем класс для цели var self = this;//дабы удобнее было ссылаться на себя var direction = 1;//куда летим? var difficulty = document.getElementById('score').innerHTML*1; //небольшой модификатор сложности ;) this.obj = document.createElement('div'); this.obj.setAttribute('id','target'); document.body.appendChild(this.obj); setInterval(function(){ var x = self.obj.style.left.toString().noPx(); //x = x.noPx(); if(x > 100){//летать будем в диапазоне (0...100)px direction = -1; }else if( x < 0){ direction = 1; } x += (2 + difficulty) * direction;//инкрементим позицию по Х с заданным знаком self.obj.style.left = x + 'px'; }, 40); } var Bullet = function(from){ var self = this; this.obj = document.createElement('div'); this.obj.setAttribute('class','bullet'); this.obj.style.left = from.obj.style.left; document.body.appendChild(this.obj); setInterval(function(){//тут мы слушаем, что случается с нашей пулей //а также, производим с ней необходимые манипуляции var bot = self.obj.style.bottom.noPx(); var top = $(self.obj).position().top; if(top < 0){ $(self.obj).trigger('collect'); } var pos = $(self.obj).position(); var tar = document.getElementById('target'); if(tar){//Собственно вот тут и начинаем проверять коллизии объектов var tar_pos = $(tar).position();//получаем позицию цели if(Math.abs((pos.left+2) - (tar_pos.left+15)) < 15){ /*(тут небольшая хитрость - точнее костыль в идеале, надо было бы к координатам прибавлять половины ширины и высоты элементов, при этом получая их центр) примерно найдем центр элементов, что пули, что объекта Далее, смотрим, если расстояние по Х между этими центрами меньше половины цели, то значит у нас есть попадание по Х, проверяем дальше*/ if(Math.abs((pos.top - 7) - (tar_pos.top-5)) < 10){ /* Тоже самое делаем и по Y, правда я решил немного расширить диапазон попадания, из-за того, что пуля может просто "перескочить" цель из-за большого инкремента по Y */ document.body.removeChild(tar);//Удаляем сбитую цель var target = new Target();//тут же создаем новую, мы же азартные ребята, играем на счет, верно? $(document).trigger('hit');//Триггерим событие попадания } } } //console.log(top); bot += 20;//Тут инкрементим позицию пули по оси Y self.obj.style.bottom = bot + 'px'; }, 50); } var Cannon = function(){ var self = this; this.loaded = true; this.obj = document.createElement('div'); this.obj.setAttribute('class','cannon loaded'); this.fire = function(){//Стреляем if(self.loaded){//Только если заряжены self.loaded = false; var bullet = new Bullet(self);//Стреляем собссно пулей(забавно, да?) self.reload();//перезаряжаемся } } this.reload = function(){//вот таким образом self.obj.classList.remove('loaded'); setTimeout(function(){ self.loaded = true; self.obj.classList.add('loaded'); }, 1000); } document.body.appendChild(this.obj);//прикручиваем пушку к документу self.obj.addEventListener('click', self.fire, false);//следим за тем, когда нажмут на курок $(document).on('collect', '.bullet', function(){//собираем пульки, улетевшие за горизонт $(this).remove(); }); $(document).on('hit', function(){//а тут увеличиваем счетчик, для удовлетворения нашего самолюбюия var score = $('#score').text(); $('#score').text(++score); }) } var tar = new Target();//Создаем пушку var can = new Cannon();//Создаем цель
#target{ display: block-inline; position: absolute; left: 0px; width: 30px; height: 10px; background-color: red; } #score_wrap{ float: right; } .cannon{ display: block-inline; position: absolute; bottom: 0px; left: 50px; width: 7px; height: 35px; background-color: lightblue; } .cannon.loaded{ border-bottom: 10px solid green; } .bullet{ display: block-inline; position: absolute; bottom: 0px; left: 50px; width: 5px; height: 15px; background-color: yellow; border-top-left-radius: 2px; border-top-right-radius: 2px; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <span id="score_wrap">Score <span id='score'>0</span></span>
More detailed explanations ( many of which are personal opinions ):
So, first of all, for me such things are easier and wiser to do through Objects, in our case these are:
var Target = function(){//Здесь, Target - имя своеобразного класса в JS this.param = ...//А здесь мы перечисляем его свойства и методы //т.е. то, что он имеет в себе, и что умеет делать ... }
This is done in order to make the entities (objects) more independent, laying the whole logic of their work in them themselves, rather than arranging the intricacies of the functions between them. It is also convenient to refer to their properties and methods, you can create several instances of the same object (for example, we create bullets and targets) and they will all behave identically, which is also convenient in our case.
Continuing the main idea, inside each object (its function), we ask, let's say, the Main function , which will perform all the basic actions with our object. But, in the way that we need to perform these actions in time , we declared this function through setInterval(функция, промежуток_в_мс) .
Thus, our function is performed with a certain periodicity, observing whether the objects that have coordinates, and so on intersect. In this case, the smaller the gap, the "smoother" the changes will be on the screen (but at the same time and faster), however, this will lead to an increase in the resource intensity of the script. Therefore, not every such function needs to set minimum execution intervals.