Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Вопросы по Canvas (https://javascript.ru/forum/misc/30560-voprosy-po-canvas.html)

daima 08.08.2012 15:59

Вопросы по Canvas
 
Изучаю как сделать игрушку на html5 и canvas по мануалу http://habrahabr.ru/post/125857/ Проблема в том, что чел., который писал ман. решил воспользоваться левым фреймворком (CraftyJS). Я решил переписать его без фреймворка и столкнулся с такой проблемой: человек перемещается - соотв. часть холста где он был ранее надо очистить. Но если я это сделаю, я сотру траву тоже. z-index canvas не поддерживает. Как быть?

Deff 08.08.2012 16:04

daima,
ну в двух канвасах сделать, либо все точки места позиции перемещения запоминать в буфер - с началом движения -восстанавливаем место где чел был и перирисовываем чела в новое(хотя не спец по канвe) должны быть и методы лучше

Hekumok 08.08.2012 16:34

daima, делайте в 2-х canvas'ах - в одном всё, что не изменяется, а во втором - наоборот, всё, что изменяется и перерисовывается... позиционируете канвы друг над другом (они ведь прозрачные) и всё

daima 08.08.2012 17:53

Цитата:

Сообщение от Deff (Сообщение 195642)
daima,
ну в двух канвасах сделать, либо все точки места позиции перемещения запоминать в буфер - с началом движения -восстанавливаем место где чел был и перирисовываем чела в новое(хотя не спец по канвe) должны быть и методы лучше

http://tlt-dessert.narod.ru/simplerpg/index.html - ну тут один канвас, поэтому видимо как-то копируют место в буфер. вопрос только как?

а идея с несколькими канвасами мне почему-то :nono: не нравится

vadim5june 08.08.2012 17:57

Цитата:

Сообщение от daima (Сообщение 195683)
http://tlt-dessert.narod.ru/simplerpg/index.html - ну тут один канвас, поэтому видимо как-то копируют место в буфер. вопрос только как?

может быть полный рендеринг-все перерисовывают

Hekumok 08.08.2012 18:30

Цитата:

Сообщение от vadim5june (Сообщение 195686)
может быть полный рендеринг-все перерисовывают

Если в канве много объектов, то это очень ресурсозатратно, поэтому иногда может быть видно, как всё перерисовывается...

Hekumok 08.08.2012 18:32

Цитата:

Сообщение от daima (Сообщение 195683)
а идея с несколькими канвасами мне почему-то :nono: не нравится

Ну как хотите, а я делаю именно так - использую 2 canvas'a

vadim5june 08.08.2012 18:41

Цитата:

Сообщение от Hekumok (Сообщение 195699)
Ну как хотите, а я делаю именно так - использую 2 canvas'a

я тоже видел игры с нексколькими канвасами с одним только самые простые-может здесь этот случай

daima 08.08.2012 18:49

допустим у нас стратегия с кучей солдат, которые куда-то несутся или много деревьев и анимированных зданий. Ваять кучу канвасов?

Цитата:

Сообщение от daima
я тоже видел игры с нексколькими канвасами

- можно ссылки?

Hekumok 08.08.2012 18:55

Цитата:

Сообщение от daima (Сообщение 195705)
допустим у нас стратегия с кучей солдат, которые куда-то несутся или много деревьев и анимированных зданий. Ваять кучу канвасов?

Кто-то говорил про кучу канвасов? Я говорил про 2, только 2, канваса, где на одном - всё, что не изменяется (не перерисовывается), а на другом - наоборот, всё, что изменяется и перерисовывается!
Я даж где-т читал, что лучше всего использовать 2 канваса так, как написано выше...и именно 2, а не больше

vadim5june 08.08.2012 19:09

Цитата:

Сообщение от daima (Сообщение 195705)
- можно ссылки?

в той ссылке на игру что Вы дали куча канвасов(6 или 8)
посмотрите html код

daima 08.08.2012 23:04

Цитата:

Сообщение от vadim5june (Сообщение 195714)
в той ссылке на игру что Вы дали куча канвасов(6 или 8)
посмотрите html код

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script src="js/jquery.js" type="text/javascript">
<script src="js/crafty.js" type="text/javascript">
<script src="js/objects/flower.js" type="text/javascript">
<script src="js/objects/bush.js" type="text/javascript">
<script src="js/objects/grass.js" type="text/javascript">
<script src="js/objects/unit.js" type="text/javascript">
<script src="js/objects/player.js" type="text/javascript">
<script src="js/objects/fourway_ai.js" type="text/javascript">
<script src="js/objects/monster.js" type="text/javascript">
<script src="js/scenes/loading.js" type="text/javascript">
<script src="js/scenes/main.js" type="text/javascript">
<script src="js/scenes/win.js" type="text/javascript">
<script src="js/scenes/lose.js" type="text/javascript">
<script src="js/game.js" type="text/javascript">
<link charset="utf-8" media="screen" type="text/css" href="css/game.css" rel="stylesheet">
<title>Simpe RPG</title>
</head>
<body>
<i style="background:url(//www.tns-counter.ru/V13a****yandex_ru/ru/CP1251/tmsec=narod_total/0)"></i>
<script type="text/javascript" src="//mc.yandex.ru/metrika/watch.js">
<div style="display:none;">
<script type="text/javascript">
</div>
<noscript><div><img src="//mc.yandex.ru/watch/9281845%%ut%%" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
<div id="cr-stage" style="width: 400px; height: 320px; overflow: hidden; position: relative; background: none repeat scroll 0% 0% rgb(0, 0, 0);">
<div style="position: absolute; z-index: 1;"></div>
<canvas width="400" height="320" style="position: absolute; left: 0px; top: 0px;"></canvas>
</div>
</body>
</html>


Всего 1

vadim5june 08.08.2012 23:50

Цитата:

Сообщение от daima (Сообщение 195767)
Всего 1

Вы ссылку давали
http://www.pirateslovedaisies.com/
там их 8
<div id="piratesLoveDaisies">
    	
        <canvas id="fallingDaisies1" width="980" height="700" style="position: absolute; top: 0px; "></canvas>
           	  
		<div id="preloader">
            <canvas id="preloaderBar" width="240" height="36"></canvas>
			<img src="img/ui/preloaderGraphic.png" width="488" height="386" />
		</div>
        
        <canvas id="fallingDaisies2" width="980" height="700" style="position: absolute; top: 0px; "></canvas>

здесь 3 остальные найдете

daima 09.08.2012 13:24

хм. надо посмотреть. пока что вожусь с буфером.
var canvas = document.getElementById('scene');
c = canvas.getContext('2d');
дальше в с чего-то рисуем. Теперь пытаюсь закешировать некую область :


var cache_canvas = document.createElement('canvas').getContext('2d');
cache_canvas.drawImage(c,0,0,16,16,100,100,16,16);

и фаирбаг мне пишет NS_ERROR_XPC_BAD_CONVERT_JS: Could not convert JavaScript argument arg 0 [nsIDOMCanvasRenderingContext2D.drawImage] как же сделать копию области?

vadim5june 09.08.2012 13:31

Цитата:

Сообщение от daima
как же сделать копию области?

ctx.getImageData(x,y,w,h)
а обратно
ctx.putImageData(ImageData,x,y)

daima 10.08.2012 11:21

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

и еще вопросы. есть объект Цветок:

var wind;
var pos=0;
var flower= {

init: function(x,y,sprite){

function animateFlower(){
	c.putImageData(cache_canvas,x,y);
	var imgFlower=new Image();
	imgFlower.src=sprite.spriteimg;
	c.drawImage(imgFlower,(sprite.flower[0]+pos)*16,sprite.flower[1]*16,16,16,x,y,16,16)
	pos<3 ? pos++ : pos=0;
x+=16;

}


var cache_canvas=c.getImageData(x,y,16,16)
animateFlower();
wind=setInterval(animateFlower,500)
},
clear: function(){
	clearInterval(wind);
}
}

где х, у - координаты места на холсте, sprite - ссылка на спрайт-объект
Инициализируем flower.init(100, 100,sprite);

во время анимации его координата х меняется.

1. Как мне ее получить чтобы потом обрабатывать столкновения? добавляю в объект flover:

posX: function(){
return x
}

но alert(flower.posX) печатает мне function(){return x}

2. допустим я захочу на игровое поле добавить еще цветок: flower.init(150, 150,sprite);

как мне теперь обратиться к нужному? например я захочу переместить 1й или 2й или скажем остановить анимацию какого-то из них

Hekumok 10.08.2012 11:30

daima, а вы это без библиотек без всяких спрайт анимируете?

vadim5june 10.08.2012 11:31

Цитата:

Сообщение от daima
правда пишут что putImageData слишком ресурсоемкий и по возм. его не использовать

по оптимизации канваса есть хорошая статья
http://www.html5rocks.com/ru/tutoria...s/performance/

daima 10.08.2012 11:50

Цитата:

Сообщение от Hekumok (Сообщение 196150)
daima, а вы это без библиотек без всяких спрайт анимируете?

var cache_canvas=c.getImageData(x,y,16,16) - запомнили подложку. а дальше ф-я animateFlower() рисует определенные куски спрайта

Caminante 10.08.2012 12:14

Цитата:

1. Как мне ее получить чтобы потом обрабатывать столкновения? добавляю в объект flover:

posX: function(){
return x
}

но alert(flower.posX) печатает мне function(){return x}
Попробуйте так:

var p = flower.posX();
alert(p);


Цитата:

2. допустим я захочу на игровое поле добавить еще цветок: flower.init(150, 150,sprite);

как мне теперь обратиться к нужному? например я захочу переместить 1й или 2й или скажем остановить анимацию какого-то из них
Можно присвоить создаваемый объект переменной и таким образом обращаться к ней. Например, var rose = flower.init(150, 150,sprite). Если цветов будет много, можно создать для них массив и обращаться по порядковому номеру.

Hekumok 10.08.2012 12:39

Цитата:

Сообщение от daima (Сообщение 196159)
var cache_canvas=c.getImageData(x,y,16,16) - запомнили подложку. а дальше ф-я animateFlower() рисует определенные куски спрайта

Ааааа :D спасибо :)

daima 14.08.2012 13:31

Цитата:

Сообщение от Caminante (Сообщение 196168)
Попробуйте так:

var p = flower.posX();
alert(p);




Можно присвоить создаваемый объект переменной и таким образом обращаться к ней. Например, var rose = flower.init(150, 150,sprite). Если цветов будет много, можно создать для них массив и обращаться по порядковому номеру.

Пишет undefined. Возможно что-то я не так написал. Полный код:
var flower= {

init: function(x,y,sprite){
var wind;
var pos=0;
function animateFlower(){код анимации цветка}
var cache_canvas=c.getImageData(x,y,16,16)
animateFlower();
wind=setInterval(animateFlower,500)
},
clear: function(){
	clearInterval(wind);
}

}


Запускаем var rose = flower.init(150, 100,sprite); где 150 - позиция по х, 100 - позиция по y.

1. Что мне нужно написать в коде чтобы считывать позицию по х и y и как будет выглядеть этот вызов? rose.posX?
2. когда чел наступит на цветок - его нужно удалить. для этого я ввел ф-ю clear только непонятно как добраться до ссылки на таймер wind и как ее в этом случае запустить.

Caminante 14.08.2012 13:53

Цитата:

Сообщение от daima
Что мне нужно написать в коде чтобы считывать позицию по х и y и как будет выглядеть этот вызов? rose.posX?

Нужно соответствующую функцию добавить и вызвать. Вообще сейчас у создаваемого вами цветка нет свойства x. Как вариант, можно было бы сделать так:

function Flower(x, y)
{
this.x = x;
this.y = y;
this.posX = function(){return this.x};
}

var rose = new Flower(10, 20);
      
alert(rose.posX());

daima 14.08.2012 14:53

Цитата:

Сообщение от Caminante (Сообщение 197436)
Нужно соответствующую функцию добавить и вызвать. Вообще сейчас у создаваемого вами цветка нет свойства x. Как вариант, можно было бы сделать так:

экий ты шустый. Ты исходный код видел? надо в нем как-то исхитриться
ВО! Переписал.
var flower= {

init: function(x,y,sprite){
var wind;
var pos=0;
function animateFlower(){//alert(cache_canvas);
	c.putImageData(cache_canvas,x,y);
	var imgFlower=new Image();
	imgFlower.src=sprite.spriteimg;
	c.drawImage(imgFlower,(sprite.flower[0]+pos)*16,sprite.flower[1]*16,16,16,x,y,16,16)
	pos<3 ? pos++ : pos=0;
}
this.posX = x;
this.posY = y;
var cache_canvas=c.getImageData(x,y,16,16)
animateFlower();
this.wind=setInterval(animateFlower,500)
},
clear: function(){
	clearInterval(this.wind);
},
}


Допустим, хотим несколько цветков: var rose[0] = flower.init(150, 200,sprite); var rose[1] = flower.init(150, 100,sprite); Теперь, как получить позицию скажем rose[1]?

Caminante 14.08.2012 16:18

На что ссылается this в вашем коде?
Попробуйте создать var rose = flower.init(150, 200,sprite) и запросить rose.posX и flower.posX.

daima 14.08.2012 16:45

Цитата:

Сообщение от Caminante (Сообщение 197513)
На что ссылается this в вашем коде?
Попробуйте создать var rose = flower.init(150, 200,sprite) и запросить rose.posX и flower.posX.

<script>

var flower= {

init: function(x,y){
var wind;
var pos=0;
function animateFlower(){
}
this.posX = x;
this.posY = y;
return this;
},
clear: function(){
	clearInterval(this.wind);
}
}

var rose=new Array();
for(var i = 0; i < 2; i++) {
   		  rose.push(flower.init(i*100, i*100));
	  }

alert(rose[0].posX+" "+rose[0].posY+" "+rose[1].posX+" "+rose[1].posY);
</script>

Непонятно мне, почему возвращаются координаты последнего объекта

Caminante 14.08.2012 17:06

Цитата:

Сообщение от daima
Непонятно мне, почему возвращаются координаты последнего объекта

В цикле изменяются x и y объекта flower, которые после второй итерации равны 100. В массив при этом оба раза записывается один и тот же объект flower (можно проверить rose[0] === flower).

daima 14.08.2012 17:12

беда :( Как же быть то?

Caminante 15.08.2012 09:58

Можно посмотреть в сторону предложенного мной сначала решения. Или еще такой вариант:

function createObject(x, y)
{      
   return {x: x, y: y}
}
          
var o = createObject(2,3);
var o2 = createObject(7,8);

daima 15.08.2012 10:34

Цитата:

Сообщение от Caminante (Сообщение 197696)
Можно посмотреть в сторону предложенного мной сначала решения. Или еще такой вариант:

не-не-не, так не пойдет.
У нас есть объект flower, у него есть свойства init (инициализация), posX,posY - его текущие координаты, clear (удаление). Вот с ним и работаем. Никакие непонятные ф-и не нужны :nono:

Caminante 15.08.2012 10:43

Ну так добавьте функцию из предыдущего моего сообщения в ваш объект flower, если вам никак не хочется менять структуру своего кода. Чтобы ваш метод init возвращал каждый раз новый объект, а не изменял сам flower. Это ведь не так сложно.

Yes 16.08.2012 11:54

Как узнать координаты пикселя x и y?
 
Как узнать координаты пикселя x и y?

daima 16.08.2012 13:47

Ура! С этим кажись разобрались. А не видел ли кто:
1) понятный скрипт по генерации ландшафта (горы, водоемы)
2) алгроритм который позв. определить могу я в даном месте строиь здание с некими габаритами или нет

Severtain 18.08.2012 13:37

Yes,
ЧТо ? 0_0=)

Severtain 18.08.2012 13:39

Цитата:

Сообщение от daima (Сообщение 197971)
А не видел ли кто:
1) понятный скрипт по генерации ландшафта (горы, водоемы)

Видел :)

Цитата:

Сообщение от daima (Сообщение 197971)
А не видел ли кто:
2) алгроритм который позв. определить могу я в даном месте строиь здание с некими габаритами или нет

Видел :)

Ответ :
1.По 1ому напиши сам или заплати за него :) Все зависит от сложности этого алгоритма .
2. Элементарно! Находишь размеры твоего здания (это очень просто), а затем вычисляешь есть ли объект (который строится) в этой области или нет!

daima 19.08.2012 11:14

Цитата:

Сообщение от Severtain (Сообщение 198499)
Видел :)


Видел :)

Ответ :
1.По 1ому напиши сам или заплати за него :) Все зависит от сложности этого алгоритма .
2. Элементарно! Находишь размеры твоего здания (это очень просто), а затем вычисляешь есть ли объект (который строится) в этой области или нет!

А где видел-то?

Severtain 20.08.2012 10:01

daima,
Ссылки дать ?

P.S. а в чем проблема со 2ым алгоритмом? Этого я не могу понять !

DenBraun 20.08.2012 14:41

При создании игры, я разделил динамические объекты и статичные, динамические объекты анимируешь с помощью перерисовки всего canvas, а статичные вещаеш через css и в js управляеш просто их положением и все)

Severtain 20.08.2012 14:45

Но это не мешает просчитать траекторию здания! X,Y объекта + ширина и длина !

"вещаеш через css "
Плохой опыт у меня с этим! Лучше уже просто отдельный слой canvas ! Такой же эффект только возможностей больше !

DenBraun 20.08.2012 14:52

если объекты должны взаимодействовать друг с другом то все рисуешь на одном холсте, можно написать класс который эмулирует слои рендеринга, то есть чтоб манипулировать уровнем отрисовки. В CSS полезно размещать все объекты которые не включены в игровую логику а просто я вляются интерьером игры или интерфейсом.
пример: bug-wars.com/bugwars.html
один canvas элемент


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