Вход

Просмотр полной версии : javascript canvas game - конкретная тема


Seva Pletnev
15.07.2013, 16:31
Здравствуйте. Я решил создать данную тему для решения вопросов по играм. Отдельного раздела по этим вопросам на форуме нет, а жаль((( Я уже пытался найти ответы на вопросы на этом форуме http://javascript.ru/forum/dom-window/37772-canvas-prererisovaka-ehkrana-3.html но так и не добился своего. :help:

Так вот первый вопрос: как сделать проверку столкновений объектов. Меня интересует хороший и понятный способ . Я не хочу изобретать велосипед по этому кто знает ответе пожалуйста =) Это решит очень многие проблемы. Я вообще буду здесь выкладывать свои игровые скрипты и задумки. Думаю это будет интересно. :write:

mta88
15.07.2013, 17:14
Так вот первый вопрос: как сделать проверку столкновений объектов. Меня интересует хороший и понятный способ.
если бы я разбирался в написании игр, то написал бы, что существуют десятки способов с различными алгоритмами и оптимизациями, каждый из которых подходит для своего случая
но я в этом не разбираюсь и поэтому посоветую почитать форумы, где общаются игроделы, почитать книжки и поискать чего-нибудь в поисковых системах

Seva Pletnev
15.07.2013, 18:47
Я ж все canvas: пререрисовака экрана тут описывал. Да, я про прямоугольник.

Seva Pletnev
15.07.2013, 19:14
я там выкладывал код танчиков =)

Seva Pletnev
15.07.2013, 22:21
c= document.getElementById('c');g= c.getContext('2d');

var gameObject=[];
map=[
0,0,0,1,0,0,0,0,
0,1,1,1,1,1,1,0,
0,1,1,1,1,1,1,0,
0,1,1,0,0,1,1,0,
1,1,1,0,1,1,1,1,
0,1,1,1,1,1,1,0,
0,1,1,1,1,1,1,0,
0,0,0,1,0,0,0,0
];

mapClet=50;
vx=0;vy=0;

var plyer=function(xPl,yPl,col){
vec=0;
that={
xPl:xPl,
yPl:yPl,
col:col,

move: function(){
if(key==37){xPl-=mapClet; vec=0}
if(key==39){xPl+=mapClet; vec=1}
if(key==38){yPl-=mapClet; vec=2}
if(key==40){yPl+=mapClet; vec=3}
if(key==32){gameObject.push(bulletPlayer(xPl+15,yP l+15,vec,"#000"))}


},
draw: function(){
g.fillStyle=col;
g.fillRect(xPl,yPl,mapClet,mapClet);
}

};
return that;
};
var mob=function(xMb,yMb,col){
that={
xMb:xMb,
yMb:yMb,
col:col,

move: function(){},
draw: function(){
g.fillStyle=col;
g.fillRect(xMb,yMb,mapClet,mapClet);
}

};
return that;
};
var bulletPlayer=function(xBp,yBp,vec,col){
that={
xBp:xBp,
yBp:yBp,
col:col,
vec:vec,

move: function(){
if(vec==0){xBp-=mapClet}
if(vec==1){xBp+=mapClet}
if(vec==2){yBp-=mapClet}
if(vec==3){yBp+=mapClet}
},
draw: function(){
g.fillStyle=col;
g.fillRect(xBp,yBp,20,20);
}

};
return that;
};
var bulletMob=function(xBm,yBm,vec,col){
that={
xBm:xBm,
yBm:yBm,
vec:vec,
col:col,

move: function(){},
draw: function(){}

};
};
var woll=function(x,y,col){
that={
x:x,
y:y,
col:col,

move: function(){},
draw: function(){
g.fillStyle=col;
g.fillRect(x,y,mapClet,mapClet);
}

};
}
setInterval(function(){
g.clearRect(0,0,700,700);
for(n=0;n<64;n++){
x=n&7;y=n>>3;
if(map[n]==0){vx=x;vy=y}
g.fillStyle="#0f0";
g.fillRect(vx*mapClet,vy*mapClet,mapClet,mapClet);
}
gameObjectFresh=[];
for(i=0;i<gameObject.length;i++){
gameObject[i].move();
gameObject[i].draw();
if(gameObject.flag===false){
gameObjectFresh.push(gameObject[i]);
}
}
gammeObject=gameObjectFresh;
},100);

gameObject.push(plyer(200,200,"#00f"));
gameObject.push(mob(300,300,"#f00"));

document.onkeydown = keyDn; document.onkeyup = keyUp; key=0;
function keyDn(e) {key = e.which; }
function keyUp(e) {key = 0;}

Seva Pletnev
15.07.2013, 22:23
вот тут надо мне надо придумать проверку столкновений объектов.

Seva Pletnev
15.07.2013, 23:06
c= document.getElementById('c');g= c.getContext('2d');
setInterval(ris,125);

mapClet=50;

mapCol=["#ff00ff","#ff0000","#00ff00","#0000ff"];

map=[
1,1,3,1,3,1,1,1,
1,1,3,1,3,1,1,1,
1,1,3,1,3,1,1,1,
1,1,3,1,3,1,1,1,
3,1,1,1,1,1,3,1,
1,3,1,1,1,3,1,1,
1,1,3,3,3,1,1,1,
1,1,1,1,1,1,1,1
];
xq=0;yq=0;
function ris(){
switch (key){
case 37: xq--;break;
case 38: yq--;break;
case 39: xq++;break;
case 40: yq++;break;
}
g.clearRect(0,0,512,512);
for(n=0;n<64;n++){
x=n&7;y=n>>3;rx=Math.random()*25;ry=Math.random()*2;rs=Math.r andom()*2;
x=(x+xq)&7;y=(y+yq)&7;
g.fillStyle=mapCol[map[n]];
g.fillRect(x*mapClet+rx,y*mapClet+ry,mapClet-5-rs,mapClet-5-rs);
}

}
document.onkeydown = keyDn; document.onkeyup = keyUp; key=0;
function keyDn(e) {key = e.which; /*alert(key);*/ }
function keyUp(e) {key = 0;}

скроллер экрана.

Seva Pletnev
15.07.2013, 23:07
c= document.getElementById('c');g= c.getContext('2d'); //получаем контекст отрисовки 2d

x=0; y=490; //координаты платформы
xq=250; yq=100; xw=100; yw=480; //координаты игрока и моба
gravi=2; //гравитация
gamp=20; // сила прыжка
speed=0; //скорость падения
time=30; //время интервала перерисовки
live=100; //жизни игрока
Mobi=0; //переменная бегающая по массиву Mobprid
Mobprid=[4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3]; //массив содержащий индесы направлений для моба

setInterval(riswin,30); //функция перерисовки экрана

function riswin(){ //функция отрисовки игрока,платформы,моба ифона
g.clearRect(0,0,500,500); //очищаем экран
g.fillStyle="#000000";
g.fillRect(0,0,500,500); //рисуем фон
g.fillStyle="#00ff00";
g.fillRect(x,y,500,10); //рисуем платформу зеленого цвета
graviPlayer(); //вызываемфункцию игрока
scrMob();
prin();
}
function graviPlayer(){ //функция управления игроком
if(key==39) {xq+=5;} //сдвиг вправо
if(key==37) {xq-=5;} //сдвиг влево
if(yq==480){if(key==38) {speed-=gamp;}} // еслиигрок на землеи нажата клавиша вверх, то от скорости отнять силу прыжка

yq+=speed; // прибавляем к Y игрока скорость (реализуется падение)
if(yq!=480) {speed+=gravi; } // если игрок не на земле то к скорости прибавляем гравитацию каждый шаг (реализуется ускарение свободного падения)
if(yq==480){speed=0;} //если игрок на земле, мы обнуляем скорость

g.fillStyle="#0000ff";
g.fillRect(xq,yq,10,10); // рисуем игрока
if(xq>500) {xq=0;}
if(xq<0) {xq=490}
}
function scrMob() { //функция навигации моба

g.fillStyle="#ff0000";
g.fillRect(xw,yw,10,10); //рисуем моба
i=Mobprid[Mobi];
Mobi++;
if(Mobi>=Mobprid.length) {Mobi=0;} //вытаскиваем индексы направлений из массива Mobprid и задаем путь
switch(i){
case 1: yw-=5;
break;
case 2: yw+=5;
break;
case 3: xw-=5;
break;
case 4: xw+=5;
break;
}
}
function prin(){ //функция отрисовки системного теста

g.strokeStyle = "#F00";
g.font = 'bold 30px sans-serif';

g.strokeText("speed: "+speed, 10, 30); //рисуем скорость

g.strokeText("x: "+xq, 200, 30); //отрисовываем координаты игрока
g.strokeText("y: "+yq, 300, 30);

g.strokeText("key: "+key, 400, 30); //рисуем нажатую клавишу

g.strokeText("live: "+live, 10, 70); //рисуем жизни

if(live!=0){if(speed>20) {live-=5;}
if(xq==xw&&yq==yw) {live-=5;}} //отнимаем жизни если игрок привышает скорость или сталкивается с мобом

if(live==0) { g.strokeText("=game over=", 170, 250); } // конец игры если нет жизней
}

document.onkeydown = keyDn; document.onkeyup = keyUp; key=0; //сохраняем в key значение клавиши и послеее отпуска обнуляем
function keyDn(e) {key = e.which;}
function keyUp(e) {key = 0;}

платформер)))

Seva Pletnev
15.07.2013, 23:09
c= document.getElementById('c');g= c.getContext('2d'); //вызываем canvas и задаем его параметры

xq=0; yq=0; // координаты игрока
xw=16; yw=16; // координвты моба

mapDot=16; //размер клетки

// 0 уголь 1 мостовая 2 земля 3 песок 4 лес 5 трава 6 вода 7 камень
mapCol = ['#333','#936','#963','#990','#693','#396','#369',' #999']; //массив цветов
map =[5,5,5,5,5,5,5,5,1,4,4,4,4,5,5,5,5,5,3,6,6,6,6,6,6, 6,6,6,6,6,6,6,
5,5,5,5,5,5,0,5,1,4,5,5,5,5,4,5,5,5,5,3,6,6,6,6,6, 6,6,6,6,6,6,6,
0,0,5,5,5,5,0,5,1,4,5,5,5,0,0,0,4,4,4,4,4,6,6,6,6, 6,6,6,6,6,6,6,
5,0,0,5,5,5,5,5,1,4,5,5,5,0,0,0,0,5,5,5,4,4,6,6,6, 6,6,6,6,6,6,6,
5,5,5,5,5,5,5,5,1,4,5,5,5,5,0,0,0,5,5,5,5,4,4,3,6, 6,6,6,6,6,6,6,
5,5,0,0,0,5,5,5,1,4,4,4,4,4,5,5,5,5,5,5,5,5,4,4,3, 3,6,6,6,6,6,6,
5,5,5,0,0,5,5,5,1,4,5,7,7,7,7,5,5,5,5,5,5,5,5,4,4, 5,3,6,6,6,6,6,
5,5,5,5,5,5,5,5,1,1,1,1,1,1,1,1,7,5,5,5,5,0,0,5,4, 4,5,3,3,3,3,3,
1,1,1,1,1,1,1,1,1,5,5,7,7,7,7,7,1,7,5,5,5,5,0,5,5, 4,4,4,4,4,4,4,
5,5,5,5,5,5,5,5,5,5,5,5,3,3,3,3,7,1,7,5,5,5,5,5,5, 5,5,5,4,4,5,5,
4,4,4,4,4,4,4,4,4,4,5,3,3,3,6,6,3,3,1,7,5,5,5,5,5, 5,5,5,5,4,5,5,
4,4,4,4,4,4,4,4,5,4,4,3,6,6,6,6,6,3,3,1,5,5,5,5,5, 5,5,5,5,5,4,5,
6,5,5,5,5,5,5,5,5,5,4,3,6,6,6,6,6,6,3,5,1,1,1,1,1, 1,1,1,1,1,1,1,
4,6,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,3,3,5,1,5,0,5,5, 5,5,5,5,5,5,5,
4,5,6,6,6,5,5,5,5,5,5,4,5,3,6,6,3,3,5,5,1,5,0,5,5, 5,7,5,5,5,5,5,
4,4,4,4,4,4,4,4,4,4,4,5,5,5,3,3,3,5,5,5,1,5,5,5,5, 7,7,7,5,5,5,5,
5,4,5,4,4,4,5,4,4,5,4,4,5,5,4,4,4,4,4,5,1,5,5,5,7, 0,0,7,7,5,5,5,
5,4,5,4,4,4,4,4,5,4,5,5,4,4,5,4,5,4,4,5,1,5,5,5,7, 7,7,7,7,5,5,5,
5,4,4,5,4,5,4,5,4,4,4,4,4,5,4,5,4,4,5,5,1,5,5,5,7, 0,7,7,5,5,5,5,
5,5,5,4,4,5,4,5,4,4,4,4,4,4,5,4,4,5,4,4,1,5,5,5,7, 0,0,7,5,5,5,5,
4,4,4,4,4,4,4,5,4,5,4,4,5,4,5,5,5,5,4,5,1,5,5,5,7, 7,7,7,5,0,0,5,
5,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,1,5,0,5,7, 7,7,7,0,0,0,0,
4,4,4,5,5,5,2,2,2,2,5,5,5,5,5,5,5,5,4,5,1,5,5,5,7, 7,0,7,5,0,0,5,
5,5,4,4,5,5,2,2,2,2,5,5,5,5,5,5,5,5,4,4,1,5,5,5,5, 7,7,7,5,0,0,5,
5,4,4,5,5,5,2,2,2,2,5,5,5,5,5,5,5,5,4,4,1,5,5,5,5, 5,7,5,5,0,5,5,
4,5,4,5,5,5,2,2,2,2,5,5,5,5,5,5,5,5,4,4,1,5,5,5,5, 5,5,5,5,5,5,5,
5,4,4,5,5,5,2,2,2,2,5,5,5,5,5,5,5,5,4,5,1,5,5,0,5, 5,5,0,0,5,5,5,
4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,1,5,5,0,5, 5,5,0,0,5,5,5,
5,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,1,5,5,0,5, 5,5,5,0,0,5,5,
4,4,4,5,4,4,4,4,4,5,5,5,4,4,5,5,5,4,4,4,1,5,5,5,5, 5,5,5,5,5,5,5,
4,4,4,4,4,5,4,4,4,4,5,5,4,5,4,5,5,4,4,4,1,5,5,5,5, 5,5,5,5,5,5,5,
5,5,3,5,4,5,5,4,5,4,4,4,4,5,4,4,5,5,4,4,1,5,5,5,5, 5,5,5,5,5,5,5]; //массив содержащий индексы клеток
// 1 вверх 2 вниз 3 влево 4 вправо
Mobprid=[1,1,1,1,4,4,4,1,1,1,1,4,4,4,4,2,2,2,2,3,3,3,3,4,2, 2,2,2,1,1,1,1,4,4,4,4,2,2,2,2,3,3,3,3,3,3,3,3]; //массив содержащий путь моба
Mobi=0;


w= c.width; h= c.height;
setInterval('run()', 100); // таймер перерисовки экрана

function run() {
g.clearRect(0,0,w,h);

for (n=0; n<1024; n++){ //цыкл переберающий массив
y=n>>5;x=n&31;
z=map[n];
g.fillStyle=mapCol[z]; //рисуем клетку цвета соответствующему индексу из массива map
g.fillRect(x*mapDot,y*mapDot,mapDot,mapDot);
}
scrPlayer(); //вызываем игрока
scrMob(); //вызываем моба
}



function scrPlayer(){
switch (key){ //проверка нажатия клавишь
case 37: xq--;
break;
case 38: yq--;
break;
case 39: xq++;
break;
case 40: yq++;
break;
case 32: yq=0; xq=0;
break;
}
g.fillStyle="#0000ff";
g.fillRect(xq*mapDot,yq*mapDot,mapDot,mapDot); //рисуем игрока (синий)
if(xq==xw&&yq==yw) {alert(":p game over")} //проаеряем столкновение с мобом
}



function scrMob() {

g.fillStyle="#ff0000";
g.fillRect(xw*mapDot,yw*mapDot,mapDot,mapDot); //рисуем моба
i=Mobprid[Mobi];
Mobi++;
if(Mobi>=Mobprid.length) {Mobi=0;} //вытаскиваем индексы направлений из массива Mobprid и задаем путь
switch(i){
case 1: yw--;
break;
case 2: yw++;
break;
case 3: xw--;
break;
case 4: xw++;
break;
}
}


document.onkeydown = keyDn; document.onkeyup = keyUp; key=0;
function keyDn(e) {key = e.which; /*alert(key);*/ }
function keyUp(e) {key = 0;}

отрисовка карты.

Seva Pletnev
15.07.2013, 23:14
Понимаете, если реалезовать этот обработчик событий можно будет сделать все!

Seva Pletnev
15.07.2013, 23:47
Если кому понравились эти скрипты - отпишитесь, я буду очень благодарен и буду писать их дальше =)

vadim5june
16.07.2013, 09:20
отрисовка карты.
Помоему лучше сделать 2 канваса-один-это фон-который как я понял не меняется-а его перерисовка займет львиную долю времени
Над фоном второй канвас с двигающимися объектами

dmitriymar
16.07.2013, 09:28
Здравствуйте. Я решил создать данную тему для решения вопросов по играм
Лучше реши свой вопрос с пониманием основ, а потом уже решай чужие вопросы

Seva Pletnev
16.07.2013, 09:41
ну что не так с моим пониманием основ?

Seva Pletnev
16.07.2013, 09:44
http://stackoverflow.com/questions/2752349/fast-rectangle-to-rectangle-intersection хороший пример, а если объектов 1000 и более?

dmitriymar место того, чтобы постоянно говорить о моем плохом понимании основ, помогли бы лучше, а то от ваших сообщений толку - 0.

dmitriymar
16.07.2013, 10:19
dmitriymar место того, чтобы постоянно говорить о моем плохом понимании основ, помогли бы лучше, а то от ваших сообщений толку - 0.
тебе так кажется, потому что ты неимоверно глуп, а хочешь выглядеть умным , что невозможно без понимания основ, какие везде описаны, впрочем как и алгоритмы для реализации. Достаточно лишь научится читать, и задумываться над прочитанным , а не получив 100 ответов кричать, что на его вопрос не ответили потому что, он ответов не может понять, только потому что, основ не знает

Мало того, твой бред от незнания основ, прочитают другие и начнут городить используя его

Seva Pletnev
16.07.2013, 11:56
Вы преувеличиваете и переигрываете. На мой вопрос про объекты ответил конкретно и ясно только Дзен-трансгуманист за что ему большое спасибо. Потом говорить такие вещи о человеке в данном случае можно только воображая. Из всех приведенных мне примеров другими людьми я все прекрасно понимал и потом использовал их. То о чем говорите вы - просто сказка =). А на форумах я сижу ради того, чтобы найти ответы на вопросы и только. Где я тут хотел выглядеть умным? Я не чего этого не делал... И поэтому так называть людей просто низко. И вообще данные разговоры выходят за пределы темы форума. Я понимаю, что таким "крутым" в области знания js кажется, что все люди знающие его еще не так хорошо как вы - глупы, но все может быть и не так. Я вообще не понимаю как вот так можно осуждать человека. Да и кто давал вам такое право? Низость да и только.

dmitriymar
16.07.2013, 14:56
. Я вообще не понимаю как вот так можно осуждать человека. Да и кто давал вам такое право? Низость да и только.
ты и дал этим постом:
Я уже пытался найти ответы на вопросы на этом форуме canvas: пререрисовака экрана но так и не добился своего
поэтому вспоминай что пишешь, и не пытайся манипулировать -не выйдет Я понимаю, что таким "крутым" в области знания js кажется, что все люди знающие его еще не так хорошо как вы - глупы, но все может быть и не так. Я вообще не понимаю как вот так можно осуждать человека. Да и кто давал вам такое право? Низость да и только.

Seva Pletnev
17.07.2013, 18:04
спасибо. Думал тут есть люди.