Javascript-форум (https://javascript.ru/forum/)
-   Ваши сайты и скрипты (https://javascript.ru/forum/project/)
-   -   как бы танки (https://javascript.ru/forum/project/60347-kak-tanki.html)

zlodiak 23.12.2015 18:08

как бы танки
 
ребята, помогите пожалуйста обзором кода

начал писать игру про танки, но уже сейчас чувствую, что нахреновертил. скрипт довольно большой, поэтому залил его на codepen

тут слабых мест очень много, поэтому меня прежде всего интересует насколько правильно я реализовал объект Tank. привожу его здесь полностью:
Tank = function(id){ 
	var	self = this,
			DIRECTION = ['up', 'right', 'bottom', 'left'];

	this.Create = function(){
		self.direction = DIRECTION[helper.randomIntFromZero(4)];

		var	tank = $('<div class="tank" id="' + self.id + '"></div>').css({
			left: self.x_coord + 'px',
			top: self.y_coord + 'px'
		});

		$('#board').append(tank);
	}

	this.checkArrowDirection = function(){
		switch (self.direction) {
	   case 'up':
	      self.arrow = '▲';
	      break
	   case 'right':
	      self.arrow = '►';
	      break
	   case 'bottom':
	      self.arrow = '▼';
	      break
	   case 'left':
	      self.arrow = '◄';
	      break		      
	   default:
	   		console.log('error arrow direction');
	      break
		}
	}

	this.checkBorderCollision = function(){
		switch (self.direction) {
	   case 'up':
	      self.y_coord -= 10;
	      if(self.y_coord <= 0) self.y_coord = 0; 
	      break
	   case 'right':
	      self.x_coord += 10;
	      if(self.x_coord >= 480) self.x_coord = 480;
	      break
	   case 'bottom':
	      self.y_coord += 10;
	      if(self.y_coord >= 480) self.y_coord = 480;
	      break
	   case 'left':
	      self.x_coord -= 10;
	      if(self.x_coord <= 0) self.x_coord = 0;
	      break		      
	   default:
	   		console.log('error direction definition');
	      break
		}
	}

	this.checkChangeDirection = function(){
		if(helper.randomIntFromZero(100) > 75){
			self.direction = DIRECTION[helper.randomIntFromZero(4)];
		}
	}

	this.Offset = function(){
		$('#' + self.id).css({
			left: self.x_coord + 'px',
			top: self.y_coord + 'px'
		}).html(self.arrow);
	}

	this.Move = function(){
		self.checkChangeDirection();
		self.checkBorderCollision();
		self.checkArrowDirection();
		self.Offset();
	};

	this.x_coord = helper.randomIntFromZero(481);
	this.y_coord = helper.randomIntFromZero(481);
	this.id = id;	
	this.arrow;	
	this.direction;
	
	this.Create();
}


но буду рад и критике по остальному коду

Vlasenko Fedor 23.12.2015 18:44

Где прототипы?
Свои классы на прототипах

zlodiak 24.12.2015 18:01

а вот так получше стало? что ещё из явных косяков можно доработать?

Tank = function(id){ 
  this.x_coord = helper.randomIntFromZero(481);
  this.y_coord = helper.randomIntFromZero(481);
  this.id = id; 
  this.arrow; 
  this.direction;
  this.DIRECTION = ['up', 'right', 'bottom', 'left'];

  this.Create();
}

Tank.prototype.Create = function(){
  this.direction = this.DIRECTION[helper.randomIntFromZero(4)];

  var tank = $('<div class="tank" id="' + this.id + '"></div>').css({
    left: this.x_coord + 'px',
    top: this.y_coord + 'px'
  });

  $('#board').append(tank);
}

Tank.prototype.checkArrowDirection = function(){
  switch (this.direction) {
   case 'up':
      this.arrow = '▲';
      break
   case 'right':
      this.arrow = '►';
      break
   case 'bottom':
      this.arrow = '▼';
      break
   case 'left':
      this.arrow = '◄';
      break         
   default:
      console.log('error arrow direction');
      break
  }
}

Tank.prototype.checkBorderCollision = function(){
  switch (this.direction) {
   case 'up':
      this.y_coord -= 10;
      if(this.y_coord <= 0) this.y_coord = 0; 
      break
   case 'right':
      this.x_coord += 10;
      if(this.x_coord >= 480) this.x_coord = 480;
      break
   case 'bottom':
      this.y_coord += 10;
      if(this.y_coord >= 480) this.y_coord = 480;
      break
   case 'left':
      this.x_coord -= 10;
      if(this.x_coord <= 0) this.x_coord = 0;
      break         
   default:
      console.log('error direction definition');
      break
  }
}

Tank.prototype.checkChangeDirection = function(){
  if(helper.randomIntFromZero(100) > 75){
    this.direction = this.DIRECTION[helper.randomIntFromZero(4)];
  }
}

Tank.prototype.Offset = function(){
  $('#' + this.id).css({
    left: this.x_coord + 'px',
    top: this.y_coord + 'px'
  }).html(this.arrow);
}

Tank.prototype.Move = function(){
  this.checkChangeDirection();
  this.checkBorderCollision();
  this.checkArrowDirection();
  this.Offset();
}

рони 24.12.2015 18:15

zlodiak,
а где проверка что танк не по танку едет? :)

zlodiak 24.12.2015 20:25

Цитата:

Сообщение от рони (Сообщение 401258)
zlodiak,
а где проверка что танк не по танку едет? :)

ну нееееет, это функциональность. её я нарастить всегда успею. мне сейчас важнее чтобы с точки зрения архитектуры и чистоты кода всё было хорошо

например меня беспокоит сам цикл игры(который в setInterval). берут меня сомнения, может быть лучше вынести всё это в отдельный 'класс' и рассылать события подписчикам? не лишнее здесь это будет, как думаете, зубры яваскрипта?)

zlodiak 26.12.2015 13:16

Цитата:

Сообщение от рони (Сообщение 401258)
zlodiak,
а где проверка что танк не по танку едет? :)

всё таки вот сделал проверку чтобы танки не ездили друг по другу: http://codepen.io/anon/pen/PZGeGb

моё решение совсем неудачное с точки зрения производительности? если я потом ещё сделаю стены, деревья и т.п., то не будет ли игра тормозить от такого количества проверок?

Tank.prototype.checkTankCollision = function(){
	self = this;

	Tank.tanks.forEach(function(tank){
		var	x1 = self.x_coord,
				x2 = self.x_coord + Tank.tankSize,
				y1 = self.y_coord,
				y2 = self.y_coord + Tank.tankSize,
				x3 = tank.x_coord,
				x4 = tank.x_coord + Tank.tankSize,
				y3 = tank.y_coord,
				y4 = tank.y_coord + Tank.tankSize;

		if(self.id != tank.id){
			if((y2 >= y3 && y2 <= y4) && ((x2 >= x3 && x2 <= x4) || (x1 <= x4 && x1 >= x3))){
				console.log('collision: ' + self.id + ' and ' + tank.id);
				self.y_coord -= 10;
				tank.x_coord += 10;
			};

			if((y4 >= y1 && y4 <= y2) && ((x4 >= x1 && x4 <= x2) || (x3 <= x2 && x3 >= x1))){
				console.log('collision: ' + self.id + ' and ' + tank.id);
				tank.x_coord -= 10;
				self.y_coord += 10;
			};

			if((x2 >= x3 && x2 <= x4) && ((y2 >= y3 && y2 <= y4) || (y1 <= y4 && y1 >= y3))){
				console.log('collision: ' + self.id + ' and ' + tank.id);
				self.x_coord -= 10;
				tank.x_coord += 10;
			};		

			if((x4 >= x1 && x4 <= x2) && ((y4 >= y1 && y4 <= y2) || (y3 <= y2 && y3 >= y1))){
				console.log('collision: ' + self.id + ' and ' + tank.id);
				tank.x_coord -= 10;
				self.x_coord += 10;
			};		
		}
	});	
}

рони 26.12.2015 13:25

zlodiak,
может разбить поле на квадраты и передвигаться только ним?

zlodiak 26.12.2015 13:43

это слишком просто, да движение слишком рваное получится. а я в будущем собираюсь каждому танку присвоить свою максимальную скорость, размер и другие интересные характеристики

ruslan_mart 27.12.2015 13:43

zlodiak, может лучше без jQuery? :)

Lemme 27.12.2015 17:39

zlodiak, если ты развлекаешься, то писал бы уже на es6.
Как сказал рони, разделил бы карту на квадраты.

Цитата:

да движение слишком рваное получится
Не получится, если карта разбита на квадраты, то это не значит, что они будут прыгать из квадрата в квадрат, можно же сделать плавное перемещение. Плюс, так будет проще отследить объекты в данной местности.

Я б делал нечто подобное https://jsfiddle.net/eq3dy2wz/ (тут только карта).
Написал минут за 15, так что сильно не кричите)


Часовой пояс GMT +3, время: 17:25.