Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #31 (permalink)  
Старый 19.10.2017, 00:35
Интересующийся
Отправить личное сообщение для malinovsky Посмотреть профиль Найти все сообщения от malinovsky
 
Регистрация: 07.09.2017
Сообщений: 14

Rise,
спасибо)
Ответить с цитированием
  #32 (permalink)  
Старый 19.10.2017, 00:42
Интересующийся
Отправить личное сообщение для malinovsky Посмотреть профиль Найти все сообщения от malinovsky
 
Регистрация: 07.09.2017
Сообщений: 14

Rise,
Я тут еще заметил, что объекты при столкновении удаляются не все, например, если сталкивается пуля с противником и пуля удаляется первой, то противник может остаться и продолжить движение, поэтому я немного изменил код. Теперь вроде бы работает правильно. Жду твоего мнения.
class Game
{
	constructor(canvas) {
		this.canvas = canvas;
		this.ctx = canvas.getContext('2d');
		this.world = new Set();
		this._last = 0;
		this.count = 0;
		this.world.add(new Player(this.canvas.width/2-30, this.canvas.height-30, 30, 20, "rgb(173, 105, 82)", 200));
		this.world.add(new Attack(50));
		this.lastObjShot = false;
		this._step = (now) => {
			this._loop = requestAnimationFrame(this._step);
			this.delta = Math.min(now - this._last, 100) / 1000;
			this._last = now;
			this.update();
			this.render();
		};
		this._step(0);
	}

	update() {
		for (let entity of this.world) if (entity.update) entity.update(this);
	}

	render() {
		this.ctx.fillStyle = "rgb(36, 177, 219)";
		this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
		for (let entity of this.world) if (entity.render) entity.render(this);
	}

	collide(entity1, type) {
		for (let entity2 of this.world) {
			if (entity1 != entity2  &&
				entity1.x <= entity2.x + entity2.w &&
				entity1.x + entity1.w >= entity2.x &&
				entity1.y <= entity2.y + entity2.h &&
				entity1.h + entity1.y >= entity2.y) 
				{
					if(entity1.type == (SHOT || SHIP) && entity2.type == (SHIP || SHOT))
					{
						this.world.delete(entity1);
						this.world.delete(entity2);
					}
					if(entity1.type == PLAYER && entity2.type == SHIP)
					{
						this.stop();
					}
				}	
		}
	}

	stop()
	{
		if (this._loop) this._loop = cancelAnimationFrame(this._loop);
	}
}

class Rect
{
	constructor() {
	}

	render(game) {
		game.ctx.fillStyle = this.color;
		game.ctx.fillRect(this.x, this.y, this.w, this.h);
	}
}

const PLAYER = 1, SHIP = 2, SHOT = 4, LINE = 8;

class Player extends Rect
{
	constructor(px, py, pw, ph, c, v, game) {
		super();
		Object.assign(this, { type: PLAYER, rate: 0.1, delay: 0, x : px, y : py, w : pw, h : ph, color : c, vel : v });
	}

	update(game) {

		if(keyEvent.left) {
			this.x -= this.vel * game.delta;
		}
		if(keyEvent.right) {
			this.x += this.vel * game.delta;
		}
		this.delay -= game.delta;
		if (keyEvent.space && this.delay < 0) {
			this.delay = this.rate;
			game.world.add(new Shot(this.x+11, this.y-8, 7, 7, 'red', 200));
		}
		game.collide(this);
	}
}

class Ship extends Rect
{
	constructor(px, py, pw, ph, c, v, game) {
		super();
		Object.assign(this, { type: SHIP, x : px, y : py, w : pw, h : ph, color : c, vel : v });
		game.ship = this;
	}

	update(game) {
		this.y += this.vel * game.delta;
		game.collide(this);
	}
}

class Shot extends Rect
{
	constructor(px, py, pw, ph, c, v) {
		super();
		Object.assign(this, { type: SHOT, x : px, y : py, w : pw, h : ph, color : c, vel : v });
	}

	update(game) {
		this.y -= this.vel * game.delta;
		game.collide(this);
		if(this.y < 0) game.world.delete(this);
	}
}

class Attack {
	constructor(s) {
		Object.assign(this, { size: s, rate: 0.5, delay: 0 });
	}
	update(game) {
		this.delay -= game.delta;
		if (this.delay < 0) {
			this.delay = this.rate;
			game.world.add(new Ship(Math.random() * 590, 5, 10, 10, 'green', 100, game));
			if (!--this.size) game.world.delete(this);
		}
	}
}

const keyEvent = {
	left : false,
	right : false,
	space : false
};

window.onkeydown = function(e) {
  switch(e.keyCode) {
  	case 37 : keyEvent.left = true; break;
  	case 39 : keyEvent.right = true; break;
  	case 32 : keyEvent.space = true; break;
  }
};

window.onkeyup = function(e) {
  switch(e.keyCode) {
  	case 37 : keyEvent.left = false; break;
  	case 39 : keyEvent.right = false; break;
  	case 32 : keyEvent.space = false; break;
  }
};

const game = new Game(document.getElementById('canvas'));

Последний раз редактировалось malinovsky, 19.10.2017 в 00:56.
Ответить с цитированием
  #33 (permalink)  
Старый 21.10.2017, 16:57
Профессор
Отправить личное сообщение для Rise Посмотреть профиль Найти все сообщения от Rise
 
Регистрация: 07.11.2013
Сообщений: 4,661

malinovsky,
class Game {
	constructor(canvas, ...entities) {
		// ...
		this.world = new Set(entities);
		this.cache = new Set();
		// ...
	}
	// ...
	update() {
		for (let entity of this.world) if (entity.update) entity.update(this);
		for (let entity of this.cache) {
			this.world.delete(entity);
			this.cache.delete(entity);
		}
	}
	// ...
}

class Ship extends Rect {
	// ...
	update(game) {
		// ...
		if (game.collide(this, PLAYER | SHOT | LINE )) game.cache.add(this);
	}
}

const game = new Game(canvas, new Player(), new Attack());
Ответить с цитированием
  #34 (permalink)  
Старый 25.10.2017, 00:59
Интересующийся
Отправить личное сообщение для malinovsky Посмотреть профиль Найти все сообщения от malinovsky
 
Регистрация: 07.09.2017
Сообщений: 14

Rise,
тоже самое, вот игра: https://himbotop.github.io/MFG3/
и сам код
class Start
{
    constructor(canvas, urlArr) {
        this.canvas = canvas;
        this.urlCache = {};
        urlArr.forEach((url) => {
                this.load(url);
            });
    }

    load(url) {
        let img = new Image();
        img.onload = () => {
            this.urlCache[url] = img;          
            if(this.isReady()) {
                new Game(this, 
                        new Player(this.canvas.width/2-60, this.canvas.height-100, 102, 83, this.get('img/ship.png'), 200),
                        new Attack(50));
            }
        };
        this.urlCache[url] = false;
        img.src = url;
    }

    get(url) {
        return this.urlCache[url];
    }

    isReady() {
        let ready = true;
        for(let k in this.urlCache) {
            if(this.urlCache.hasOwnProperty(k) &&
               !this.urlCache[k]) {
                ready = false;
            }
        }
        return ready;
    }
}

class Game
{
    constructor(resources, ...entities) {
        this.ctx = resources.canvas.getContext('2d');
        this.resources = resources; 
        this.terrainPattern = this.ctx.createPattern(this.resources.get('img/starfield.png'), 'repeat');
        this.world = new Set(entities);
        this.cache = new Set();
        this._last = 0;
        this.lastObjShot = false;
        this._step = (now) => {
            this._loop = requestAnimationFrame(this._step);
            this.delta = Math.min(now - this._last, 100) / 1000;
            this._last = now;
            this.update();
            this.render();
        };
        this._step(0);
    }

    update() {
        for (let entity of this.world) if (entity.update) entity.update(this);
        for (let entity of this.cache) {
            this.world.delete(entity);
            this.cache.delete(entity);
        }
    }

    render() {
        this.ctx.fillStyle = this.terrainPattern;
        this.ctx.fillRect(0, 0, this.resources.canvas.width, this.resources.canvas.height);
        for (let entity of this.world) if (entity.render) entity.render(this);
    }

    collide(entity1, type) {
        for (let entity2 of this.world) {
            if (entity1 != entity2  && 
                entity2.type & type && 
                entity1.x < entity2.x + entity2.w &&
                entity1.x + entity1.w > entity2.x &&
                entity1.y < entity2.y + entity2.h &&
                entity1.h + entity1.y > entity2.y) return true;
        }
        return false;
    }

    stop() {
        if (this._loop) this._loop = cancelAnimationFrame(this._loop);
    }
}

class Draw
{
    constructor(options) {
        const property = {
            x : null,
            y : null,
            w : null,
            h : null,
            image : null,
            vel : null
        };
        let length = 0;
        for(let prop in property) {
            property[prop] = options[length];
            length++
        }
       Object.assign(this, property);
    }

    render(game) {
        game.ctx.drawImage(this.image, this.x, this.y, this.w, this.h)
    }
}

const PLAYER = 1, SHIP = 2, SHOT = 4, LINE = 8;

class Player extends Draw
{
    constructor(...options) {
        super(options);
        Object.assign(this, { type: PLAYER, rate: 0.2, delay: 0 });
    }

    update(game) {

        if(keyEvent.left) {
            this.x -= this.vel * game.delta;
        }
        if(keyEvent.right) {
            this.x += this.vel * game.delta;
        }
        this.delay -= game.delta;
        if (keyEvent.space && this.delay < 0) {
            this.delay = this.rate;
            game.world.add(new Shot(this.x+45, this.y-30, 10, 38, game.resources.get('img/bullet.png'), 300));
        }
        if (game.collide(this, PLAYER | SHIP | LINE)) game.stop();
    }
}

class Ship extends Draw
{
    constructor(...options) {
        super(options);
        Object.assign(this, { type: SHIP });
    }

    update(game) {
        this.y += this.vel * game.delta;
        if (game.collide(this, PLAYER | SHOT | LINE )) game.cache.add(this);
    }
}

class Shot extends Draw
{
    constructor(...options) {
        super(options);
        Object.assign(this, { type: SHOT });
    }

    update(game) {
        this.y -= this.vel * game.delta;
        if (game.collide(this, SHIP | SHOT | LINE )) game.world.delete(this);
        if(this.y < 0) game.world.delete(this);
    }
}

class Attack {
    constructor(s) {
        Object.assign(this, { size: s, rate: 0.5, delay: 0 });
    }
    update(game) {
        this.delay -= game.delta;
        if (this.delay < 0) {
            this.delay = this.rate;
            game.world.add(new Ship(Math.random() * 590, 5, 66, 74, game.resources.get('img/enemy.png'), 100));
            if (!--this.size) game.world.delete(this);
        }
    }
}

const keyEvent = {
    left : false,
    right : false,
    space : false
};

window.onkeydown = function(e) {
  switch(e.keyCode) {
    case 37 : keyEvent.left = true; break;
    case 39 : keyEvent.right = true; break;
    case 32 : keyEvent.space = true; break;
  }
};

window.onkeyup = function(e) {
  switch(e.keyCode) {
    case 37 : keyEvent.left = false; break;
    case 39 : keyEvent.right = false; break;
    case 32 : keyEvent.space = false; break;
  }
};

const canvas = document.getElementById('canvas');

const start = new Start(canvas,
                        ["img/bullet.png",
                        "img/enemy.png",
                        "img/ship.png",
                        "img/starfield.png"]);
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Игры на JavaScript Вовантуз Ваши сайты и скрипты 8 06.03.2018 20:39
Прошу совета по использованию ajax ogurchik AJAX и COMET 8 14.07.2015 12:14
Python-Ajax. Прошу совета pvgdrk AJAX и COMET 11 07.11.2012 16:45
Cоздаю сайт прошу совета Геворг Ваши сайты и скрипты 5 25.01.2011 14:51
Подстроить высоту страницы под юзера, прошу совета у гуру batonsu Events/DOM/Window 11 10.11.2010 19:39