RacoonJS - Игровой движок на Canvas2D

Статус
Закрыто для дальнейших ответов.

Volter9

defined('SURRENDER') or die(); // StarWars
Регистрация
27.05.2012
Сообщения
1 145
Привет Всем! Сегодня я хочу вам представить свой игровой движок:



Название Проекта: RacoonJS
Страница Проекта: RacoonJS
Описание: RacoonJS это игровой движок для HTML5 Canvas 2D позволяет вам с легкостью создавать различные объекты, обновлять их, менять их рендеринг, предоставляет простые техники для обнаружения столкновений и небольшой класс для работы с векторами.
Последняя версия: v1.2

Демы:
  1. Asteroids
  2. Pong
  3. Shooter
  4. Planet Defender
  5. Destroyer
Пример: Для того что бы начать работать с RacoonJS вам потребуется простой HTML5 шаблон:

Код:
<!DOCTYPE html>
<html>
<head>
<title>Пример: RacoonJS</title>
<meta charset="UTF-8" />
<script src="racoon.js"></script>
<script type="text/javascript">
window.addEventListener("DOMContentLoaded",function () {
// Здесь
});
</script>
</head>
<body>
<canvas id="canvas"></canvas>
<script type="text/javascript">
(function () {
// Или здесь
})();
</script>
</body>
</html>
Там где отмечено JS комментариями, вы можете начать писать JS код где вам более удобнее, в <head> или в <body>.
(Заметьте: я использую замыкания во второй метки, т.к. если игрок будет иметь доступ к консоли он может начать жульничать! )
Теперь нам надо создать главный игровой объект и инициализировать его:

Код:
(function () {
var Game = new RJ.Game(); // Создаем игру

Game.init({ // Функция инициализации
canvas: "canvas", // Здесь идет ID канваса
size: size(640,480), // Размер, функция size(w,h) создает объект -> {w: w, h: h}
rate: 60 // FPS
});
})();
У вас по идеи должен появится черный экран. Если хотите поменять цвет заливки это сделать можно так:

Код:
// После .init
Game.pColor = "#f00";
Объект Game "наследуется" от объекта GameObject и имеет все его свойства + собственные методы.
Давайте теперь нарисуем картинку в canvas'e, вам нужна сначала картинка, я возьму эту:



А теперь к коду:

Код:
var image = new Image();
image.src = "./racoonjs.png"; // Путь к картинке

var Img = new RJ.Image({ // Картинка
name: "Image", // Имя
size: size(128,128), // Размер
pos: vec2(320,240), // Позиция - используейте функцию vec2(x,y) для задачи позиции
image: image, // Картинка
anchor: vec2(0.5,0.5) // Якорь - грубо говоря точка от которой применяются трансформации
});

Game.addChild(Img); // Добавить Img к Game
Ну вот, наша картинка готова.
Давайте сделаем так что бы она крутилась? Ок:

Код:
var Img = new RJ.Image({
// ...
anchor: vec2(0.5,0.5),
update: function () {
this.angle += 0.005;
},
});
Просто, верно?
А еще интереснее будет если она будет следовать за курсором мыши!
Код:

Код:
var Img = new RJ.Image({
// ...
anchor: vec2(0.5,0.5),
enter: function () {
this.game.mouseHandler.addHandler(this);
},
exit: function () {
this.game.mouseHandler.removeHandler(this);
},
mouseHandler: function (state, cursor) {
if (state == "move") {
this.setPos(cursor);
}
},
// ...
});
Ну вот и все. В следующий раз, я напишу как создавать "классы".
 

brevis

Well-Known Member
Регистрация
10.08.2010
Сообщения
452
Я движок как-то смотрел уже, и в игры тоже во все поиграл...
Думаю вполне имеет место быть. Желаю творческих успехов.

Кстати, вот сделал игру движке http://jsfiddle.net/CCprd/
Набравшему 100 очков -- ценный приз.

P.S. С днём программиста!

P.P.S. Может название сменить? А то какой-то чудак (на букву м конечно же) че-то такое делает https://github.com/grahamzibar/RaccoonJS
 

lekzd

parse error: parse error, unexpected T_STRING...
Регистрация
17.02.2011
Сообщения
1 125
[member=brevis], http://screenshot.su/show.php?img=a173ea8537d1b569e3ee2aefba4794d1.jpg
Жду приз, че=)
 

brevis

Well-Known Member
Регистрация
10.08.2010
Сообщения
452
скриншот_почтовой_декларации.jpg
 

lekzd

parse error: parse error, unexpected T_STRING...
Регистрация
17.02.2011
Сообщения
1 125
[member=brevis], А чего-нибудь вкусное есть?
 

brevis

Well-Known Member
Регистрация
10.08.2010
Сообщения
452
Есть и то и другое.
- Что Вы будете пить — водку или спирт?
- Ой, даже не знаю, все такое вкусное...
 

Volter9

defined('SURRENDER') or die(); // StarWars
Регистрация
27.05.2012
Сообщения
1 145
[member=brevis], молодец! Классная игра. Убил пять минут, и не одного очка не заработал.
А кто-нибудь по честному заработал хоть одно очко?
Только вот зачем такое писать:

Код:
if (cursor.x>=x && cursor.x<=x+40 && cursor.y>=100 && cursor.y<=140)
Есть же:

Код:
if (this.rect.containVec(cursor))
http://jsfiddle.net/CCprd/3/

"Классы":

Ну что давайте теперь поиграемся по полной:

Для начало нам нужен шаблон. Берем из предыдущего примера:

Код:
<!DOCTYPE html>
<html>
<head>
  <title>Пример: RacoonJS</title>
  <meta charset="UTF-8" />
  <script src="racoon.js"></script>
</head>
<body>
  <canvas id="canvas"></canvas>
  <script type="text/javascript">
   (function () {
    var Game = new RJ.Game();
   
    Game.init({
	 canvas: "canvas",
	 size: size(640,480),
	 rate: 60
    });
   })();
  </script>
</body>
</html>
Теперь вы должны создать либо пустой JS файл и присобачить его с помощью <script>:

Код:
<script type="text/javascript" src="ваш.файл.js"></script>
или создать пустой тег <script>:

Код:
<script type="text/javascript">
  // КОД
</script>
 

brevis

Well-Known Member
Регистрация
10.08.2010
Сообщения
452
Убил пять минут, и не одного очка не заработал.
А кто-нибудь по честному заработал хоть одно очко?
Это главная особенность моей игры.
А то ведь ценных призов не напасёшься.
 

Volter9

defined('SURRENDER') or die(); // StarWars
Регистрация
27.05.2012
Сообщения
1 145
"Классы":

Ну что давайте теперь поиграемся по полной:
Для начало нам нужен шаблон. Берем из предыдущего примера:

Код:
<!DOCTYPE html>
<html>
<head>
<title>Пример: RacoonJS</title>
<meta charset="UTF-8" />
<script src="racoon.js"></script>
</head>
<body>
<canvas id="canvas"></canvas>
<script type="text/javascript">
(function () {
var Game = new RJ.Game();
Game.init({
	 canvas: "canvas",
	 size: size(640,480),
	 rate: 60
});
})();
</script>
</body>
</html>
Теперь вы должны создать либо пустой JS файл и присобачить его с помощью <script>:

Код:
<script type="text/javascript" src="ваш.файл.js"></script>
или создать пустой тег <script>:

Код:
<script type="text/javascript">
// КОД
</script>
Далее мы делаем следующее:

  • Определяем глобальную переменную
  • Создаем "замыкание" (поймите меня правильно)
  • Внутрь "замыкания" кладем функции и присваиваем свойство глобальной переменной для каждой отдельной функции

От слов к делу:

Код:
var BMW = {};

(function () {
function Man (obj) {

}

BMW.Man = Man;
})();
А теперь самое интересное: каждый "класс" в этом движке имеет всегда один параметр, и этот параметр объект с разными свойствами. Сначала что нам нужно сделать это "наследовать" наш "класс":

Код:
function Man (obj) {
RJ.inherit(this,Man,RJ.GameObject,obj);
}
RJ.inherit(объект, конструктор, конструктор родителя, параметры) - имеет 4 аргумента: объект - наш объект, в данном случае это this, конструктор - функция которая создает объект т.е. в нашем примере Man, конструктор родителя - тот объект который мы хотим унаследовать, это может быть RJ.GameObject, RJ.Rectangle, RJ.Oval или RJ.Image, параметры - это тот самый объект с параметрами т.е.

А теперь давайте напишем квадрат который можно будет управлять стрелочками:

Код:
function Man (obj) {
	 this.onEnter = function () {
	 this.game.keyboardHandler.addHandler(this);
	 };

	 this.onExit = function () {
	 this.game.keyboardHandler.removeHandler(this);
	 };

	 this.moving = false;
	 this.direction = vecNull();
	 this.acceleration = 3;
	 this.keyboardHandler = function (state, key) {
	 if (state == "down") {
	 switch (key) {
	 case RJ.KeyBoard.arr_u: // up
		 this.direction.y = -1;
	 break;
	 case RJ.KeyBoard.arr_d: // down
		 this.direction.y = 1;
	 break;
	 case RJ.KeyBoard.arr_l: // left
		 this.direction.x = -1;
	 break;
	 case RJ.KeyBoard.arr_r: // right
		 this.direction.x = 1;
	 break;
	 }
	 }
	 else { // state == "down"
	 switch (key) {
	 case RJ.KeyBoard.arr_u: // up &
	 case RJ.KeyBoard.arr_d: // down
		 this.direction.y = 0;
	 break;
	 case RJ.KeyBoard.arr_l: // left &
	 case RJ.KeyBoard.arr_r: // right
		 this.direction.x = 0;
	 break;
	 }
	 }
	 };

	 this.update = function () {
	 if (!this.direction.isEmpty()) {
	 var pos = this.pos.clone();
	 pos.add(this.direction.clone().scalar(this.acceleration));
	
	 this.setPos(pos);
	 }
	 }

	 RJ.inherit(this,Man,RJ.Rectangle,obj)
}
Теперь мы можем добавить этого "чела" в игру:

Код:
<script type="text/javascript">
(function () {
var Game = new RJ.Game();

Game.init({
canvas: "canvas",
size: size(640,480),
rate: 60
});

var man = new BMW.Man({
name: "Man",
pos: vec2(320,240),
size: size(40,40),
anchor: vec2(0.5,0.5),
});

Game.addChild(man);
})();
</script>
Давайте сделаем что-нить интересное с челом:

Код:
// Чел.update
	 this.update = function () {
	 if (!this.direction.isEmpty()) {
	 var pos = this.pos.clone();
	 pos.add(this.direction.clone().scalar(this.acceleration));
	
	 var angle = this.direction.angleT(vecNull());
	 if (this.angle > angle + Math.PI/32 ||
	 this.angle < angle - Math.PI/32) {
	 var diff = (this.angle) - (angle);
	 var difs = diff / Math.abs(diff) / 10;
	 difs *= -1;
	
	 this.angle += difs;
	 }
	
	 this.setPos(pos);
	 }
	 }
Прикольно, да?
Ну и напоследок еще один прикол:

Код:
(function () {
var Game = new RJ.Game();

Game.init({
	 canvas: "canvas",
	 size: size(640,480),
	 rate: 60
});

var man = new BMW.Man({
	 name: "Man",
	 pos: vec2(320,240),
	 size: size(40,40),
	 anchor: vec2(0.5,0.5),
});

var Scene = new RJ.Scene({
	 name: "MAINSCENE",
	 enter: function () {
	
	
	 this.addChild(man);
	 },
	 update: function () {
	 var l = 50 + Math.sin((this.hue/60) * Math.PI * 2) * 50;
	 Game.pColor = "hsl("+this.hue+",100%,"+l+"%)";
	
	 this.hue ++;
	 },
});
Scene.hue = 0;

Game.addChild(man);
})();
Теперь у нас будет диско бакграунд :)

Result: http://jsfiddle.net/Volter9/5nNsg/
 
Статус
Закрыто для дальнейших ответов.
Верх Низ