first commit
703
battle.js
Normal file
@ -0,0 +1,703 @@
|
||||
/////////////////////
|
||||
const canvas = document.querySelector("#gameCanvas");
|
||||
|
||||
const intro_canvas = document.querySelector("#introCanvas");
|
||||
const text_canvas = document.querySelector("#textCanvas");
|
||||
|
||||
const ctx = canvas.getContext('2d');
|
||||
const intro_ctx = intro_canvas.getContext('2d');
|
||||
const text_ctx = text_canvas.getContext('2d');
|
||||
|
||||
const black_color = "#1B1212";
|
||||
|
||||
var game, round = 1, bot_win = 0, player_win = 0, images, arrow_down, mouse_down;
|
||||
|
||||
var key_down = []; // действия, привязанные к нажатым кнопкам
|
||||
var keyboard_pressed = []; // зажатые кнопки клавиатуры
|
||||
var btn_pressed = []; // нажатые gui кнопки канваса
|
||||
|
||||
const frame_data = [];
|
||||
|
||||
var selected_level = 1;
|
||||
|
||||
const directions = {
|
||||
"_Left" : -1,
|
||||
"_Right" : 1,
|
||||
};
|
||||
|
||||
const actions = ["punch", "jump", "block"];
|
||||
|
||||
const levels = ["gg_cabinet", "bar", "car_salon"];
|
||||
|
||||
function loaderPicture(path){
|
||||
const image = new Image();
|
||||
image.src = path;
|
||||
return new Promise((resolve, reject) => {
|
||||
image.addEventListener('load', ()=>{
|
||||
resolve(image);
|
||||
});
|
||||
image.addEventListener('error', ()=>{
|
||||
reject("Error of load");
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
function setFrameData(level){
|
||||
frame_data["Игрок"] = new FrameData(timing["player"].value);
|
||||
frame_data["Компьютер"] = new FrameData(timing[levels[level] + "_enemy_timing"].value);
|
||||
|
||||
// frame_data["Бармэн"] = new FrameData(bar_enemy_timing);
|
||||
|
||||
for(var name in frame_data){
|
||||
for(var key in frame_data[name]){
|
||||
// есть start в свойстве класса и есть такой же ключ в тайминге
|
||||
if("start" in frame_data[name][key] && frame_data[name].timing[key]){
|
||||
frame_data[name][key].start = frame_data[name].timing[key].start;
|
||||
frame_data[name][key].end = frame_data[name].timing[key].end;
|
||||
if(frame_data[name].timing[key].speed){
|
||||
frame_data[name][key].speed = frame_data[name].timing[key].speed;
|
||||
}
|
||||
if(frame_data[name].timing[key].active){
|
||||
frame_data[name][key].active = frame_data[name].timing[key].active;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function beforeGame(){
|
||||
game.start_menu = false;
|
||||
game.over = true;
|
||||
game.intro = true;
|
||||
setFrameData(selected_level);
|
||||
let player = new Player(canvas.width, canvas.height, game.images.player, 0, "player", "Игрок");
|
||||
game.player = player;
|
||||
game.characters = {
|
||||
player: player,
|
||||
enemy: new Enemy(canvas.width, canvas.height, game.images["enemy" + (selected_level + 1)], 500,
|
||||
"bot", "Компьютер",
|
||||
timing[levels[selected_level] + "_enemy_timing"].size.w,
|
||||
timing[levels[selected_level] + "_enemy_timing"].size.h,
|
||||
timing[levels[selected_level] + "_enemy_timing"].speed
|
||||
),
|
||||
// npc: new Player(canvas.width, canvas.height, images.enemy2, 800, "npc", "Бармэн", 148, 200, 2)
|
||||
}
|
||||
game.buttons.button1.caption = "";
|
||||
game.buttons.button2.caption = "";
|
||||
game.buttons.button3.caption = "";
|
||||
}
|
||||
|
||||
const keyToFrame = {
|
||||
'ArrowLeft': 'walk_Left',
|
||||
'ArrowRight': 'walk_Right',
|
||||
'ArrowDown': 'crouch',
|
||||
'q': 'punch',
|
||||
'w': 'block',
|
||||
'e': 'block_Up',
|
||||
's': 'kick_Up',
|
||||
' ': 'jump',
|
||||
// 'x,z': 'test'
|
||||
};
|
||||
|
||||
const test_actions = [
|
||||
'punch_Left',
|
||||
'kick_Left_Up',
|
||||
'crouch_Left_Down',
|
||||
'block_Left_Up',
|
||||
'stand_Left',
|
||||
'jump_Left',
|
||||
]
|
||||
|
||||
function getRand(min, max){
|
||||
min = Math.ceil(min);
|
||||
max = Math.floor(max);
|
||||
return Math.floor(Math.random() * (max - min + 1)) + min
|
||||
}
|
||||
|
||||
class Game{
|
||||
constructor(canvas, images, start = true){
|
||||
this.images = images;
|
||||
this.ui = null;
|
||||
this.start_menu = start;
|
||||
this.over = true;
|
||||
this.intro = false;
|
||||
this.timer = 0;
|
||||
this.delta = 0;
|
||||
this.interval = 3 * 1.5; // скорость обновления канваса
|
||||
this.info_animation_timer = undefined;
|
||||
this.start_screen_timer = 0;
|
||||
this.start_screen_delta = 0;
|
||||
|
||||
this.round_time = 60;
|
||||
this.round_amount = 3;
|
||||
|
||||
this.time_bar = new Button(text_ctx, 5 * 1.5, 0.2, 100 / 1.5, 50 / 1.5 );
|
||||
this.buttons = [];
|
||||
this.buttons["button1"] = new Button(text_ctx, 0.82, 2, 400, 50 );
|
||||
this.buttons["button2"] = new Button(text_ctx, 0.82, 3.5, 400, 50 );
|
||||
this.buttons["button3"] = new Button(text_ctx, 0.82, 5, 400, 50 );
|
||||
|
||||
const w = 100;
|
||||
this.buttons["q"] = new Button(text_ctx, 0.5, 0.25, w, w );
|
||||
this.buttons["w"] = new Button(text_ctx, 2, 0.25, w, w );
|
||||
this.buttons["e"] = new Button(text_ctx, 3.5, 0.25, w, w );
|
||||
this.buttons["a"] = new Button(text_ctx, 1, 1.5, w, w );
|
||||
this.buttons["s"] = new Button(text_ctx, 2.5, 1.5, w, w );
|
||||
this.buttons["d"] = new Button(text_ctx, 4, 1.5, w, w );
|
||||
this.buttons["left"] = new Button(text_ctx, 7.5, 0.25, w, w );
|
||||
this.buttons["right"] = new Button(text_ctx, 9, 0.25, w, w );
|
||||
this.buttons["down"] = new Button(text_ctx, 8.25, 1.5, w, w );
|
||||
this.buttons["space"] = new Button(text_ctx, 1.5 / 8.5, 2.75, w * 8.5, w );
|
||||
this.buttons["title"] = new Button(text_ctx, 4.5 / 3, 0.25, w * 3, w );
|
||||
this.buttons["close"] = new Button(text_ctx, 40.5, 0.5, w / 4, w / 4 );
|
||||
this.buttons["bottom_text"] = new Button(text_ctx, 0.6, 11.3, w * 5, w / 3 );
|
||||
|
||||
this.info_animation = [
|
||||
{button: "q", action: "punch_Right"},
|
||||
{button: "w", action: "block_Right"},
|
||||
{button: "e", action: "block_Right_Up"},
|
||||
{button: "s", action: "kick_Right_Up"},
|
||||
{button: "left", action: "walk_Left"},
|
||||
{button: "right", action: "walk_Right"},
|
||||
{button: "down", action: "crouch_Right_Down"},
|
||||
{button: "down_q", action: "punch_Right_Down"},
|
||||
{button: "down_w", action: "block_Right_Down"},
|
||||
{button: "space", action: "jump_Right"}
|
||||
];
|
||||
|
||||
this.ui = new UI();
|
||||
}
|
||||
|
||||
updateAll(key){
|
||||
// if(this.characters.npc.currentFrame == 0){
|
||||
// this.characters.npc.currentAction = test_actions[getRand(0, 5)];
|
||||
// }
|
||||
|
||||
if(!this.start_menu){
|
||||
ctx.drawImage(this.images["background" + (selected_level + 1)], 0, 0, canvas.width, canvas.height);
|
||||
}
|
||||
else{
|
||||
ctx.fillStyle = black_color;
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
}
|
||||
if(this.over){
|
||||
if(!this.start_menu){
|
||||
if(!this.intro){
|
||||
if(!this.buttons.button2.caption){
|
||||
setTimeout(function(){
|
||||
game.ui.clearAll();
|
||||
game.buttons.button2.background = "purple";
|
||||
game.buttons.button2.caption = "Press to continue";
|
||||
}, 1000);
|
||||
}
|
||||
else{
|
||||
this.buttons.button2.background = "purple";
|
||||
this.buttons.button2.caption = "Press to continue";
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(this.ui){
|
||||
for(var i in this.buttons){
|
||||
var button = this.buttons[i];
|
||||
if(button.caption){
|
||||
if(button.focus){
|
||||
button.background = "orange";
|
||||
}
|
||||
else{
|
||||
button.background = "purple";
|
||||
}
|
||||
}
|
||||
}
|
||||
if(game.info_animation_timer == undefined){
|
||||
this.buttons.button1.caption = "Chief cabinet";
|
||||
this.buttons.button2.caption = "Bar room";
|
||||
this.buttons.button3.caption = "Car showroom";
|
||||
}
|
||||
else{
|
||||
this.buttons.button1.caption = "";
|
||||
this.buttons.button2.caption = "";
|
||||
this.buttons.button3.caption = "";
|
||||
}
|
||||
}
|
||||
if(game.info_animation_timer != undefined){
|
||||
this.buttons.title.background = black_color;
|
||||
this.buttons.bottom_text.background = black_color;
|
||||
this.buttons.close.background = "maroon";
|
||||
}
|
||||
}
|
||||
// for(let key in this.characters){
|
||||
// this.characters[key].update();
|
||||
// }
|
||||
if(!this.over){
|
||||
if(this.player){
|
||||
this.player.update();
|
||||
}
|
||||
if(this.characters && this.characters.enemy){
|
||||
this.characters.enemy.update();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(!this.start_menu){
|
||||
this.start_screen_timer += 1;
|
||||
const vs_delay = 60;
|
||||
if(this.start_screen_timer > vs_delay){
|
||||
this.start_screen_delta += 20;
|
||||
}
|
||||
|
||||
if(!this.over && this.characters){
|
||||
this.ui.drawUserInfo(50, 50, 200, images.player_avatar, this.player, this.player.name, 210);
|
||||
this.ui.drawUserInfo(canvas.width - 250, 50, 200, images["bot_avatar" + (selected_level + 1)], this.characters.enemy, this.characters.enemy.name, -70);
|
||||
// this.ui.clearAll();
|
||||
// this.ui.drawTimeBar(intro_ctx, images.time_bar, false, 0, 1.5);
|
||||
// this.ui.drawTimeBar(text_ctx, images.time_bar_mask, true, 0, 1.5);
|
||||
}
|
||||
|
||||
if(this.intro){
|
||||
this.ui.drawStartScreen(images.player_avatar, images["bot_avatar" + (selected_level + 1)], "", this.start_screen_delta, vs_delay);
|
||||
if(this.start_screen_timer > vs_delay){
|
||||
this.ui.drawGameCaption(intro_ctx, images.fight, false, this.start_screen_delta);
|
||||
this.ui.drawGameCaption(text_ctx, images.fight, true, this.start_screen_delta);
|
||||
}
|
||||
else if(this.start_screen_timer > vs_delay / 2){
|
||||
this.ui.drawGameCaption(text_ctx, images["round" + round], false, this.start_screen_delta);
|
||||
}
|
||||
else{
|
||||
this.ui.drawGameCaption(text_ctx, images.vs, false, this.start_screen_delta);
|
||||
}
|
||||
if(this.start_screen_delta >= canvas.width / 2){
|
||||
this.ui.clearAll();
|
||||
this.intro = false;
|
||||
this.over = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(!this.over){
|
||||
this.timer++;
|
||||
}
|
||||
// 60 fps канваса, но функция выывается в interval раз реже
|
||||
this.seconds = Math.floor(this.timer / (60 / this.interval) );
|
||||
|
||||
if(this.seconds >= this.round_time && !this.over && this.characters.enemy){
|
||||
this.over = true;
|
||||
if(this.player.health.current < this.characters.enemy.health.current){
|
||||
bot_win++;
|
||||
round++;
|
||||
}
|
||||
if(this.player.health.current >= this.characters.enemy.health.current){
|
||||
player_win++;
|
||||
round++;
|
||||
}
|
||||
this.checkWin();
|
||||
}
|
||||
}
|
||||
|
||||
if(this.info_animation_timer != undefined){
|
||||
|
||||
this.buttons.q.caption = "Q";
|
||||
this.buttons.w.caption = "W";
|
||||
this.buttons.e.caption = "E";
|
||||
|
||||
this.buttons.a.caption = "A";
|
||||
this.buttons.s.caption = "S";
|
||||
this.buttons.d.caption = "D";
|
||||
|
||||
this.buttons.left.caption = "<";
|
||||
this.buttons.right.caption = ">";
|
||||
this.buttons.down.caption = "|";
|
||||
|
||||
this.buttons.space.caption = " ";
|
||||
|
||||
this.buttons.close.caption = "X";
|
||||
this.buttons.bottom_text.caption = "look or press keyboard yourself";
|
||||
|
||||
|
||||
const index = Math.round(this.info_animation_timer / 30);
|
||||
const obj = this.info_animation[index];
|
||||
if(index < this.info_animation.length){
|
||||
if(Object.keys(btn_pressed).length == 0){
|
||||
this.info_animation_timer++;
|
||||
|
||||
if(obj){
|
||||
const action = timing["player"].value[obj.action];
|
||||
const frameWidth = 224;
|
||||
const frameHeight = 200;
|
||||
const image = game.images.player;
|
||||
// const x = 100;
|
||||
// const y = 100;
|
||||
|
||||
const { start, end } = action;
|
||||
|
||||
const rate = 10;
|
||||
const frames = this.info_animation_timer % rate
|
||||
|
||||
if(this.info_animation[index - 1]){
|
||||
const previous_obj = this.info_animation[index - 1];
|
||||
const previous_button = previous_obj.button.split("_");
|
||||
if(!previous_button[1]){
|
||||
this.buttons[previous_button[0]].focus = false;
|
||||
}
|
||||
else{
|
||||
this.buttons[previous_button[0]].focus = false;
|
||||
this.buttons[previous_button[1]].focus = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const button = obj.button.split("_");
|
||||
if(!button[1]){
|
||||
this.buttons[button[0]].focus = true;
|
||||
}
|
||||
else{
|
||||
this.buttons[button[0]].focus = true;
|
||||
this.buttons[button[1]].focus = true;
|
||||
}
|
||||
|
||||
if(frames && this.player.currentFrame == 0){
|
||||
if(key_down[obj.action] != false){
|
||||
if(obj.action == "walk_Right"){
|
||||
this.player.direction = "_Right";
|
||||
}
|
||||
key_down[obj.action] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else{
|
||||
for(var i in this.buttons){
|
||||
this.buttons[i].focus = false;
|
||||
}
|
||||
for(var i in btn_pressed){
|
||||
if(this.buttons[i]){
|
||||
this.buttons[i].focus = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(this.player){
|
||||
if(Object.keys(btn_pressed).length == 0){
|
||||
var first_part = obj.action.split("_");
|
||||
}
|
||||
else{
|
||||
var first_part = this.player.currentAction.split("_");
|
||||
}
|
||||
var direction_vert = first_part[2];
|
||||
if(direction_vert == "Up"){
|
||||
var str = direction_vert.toLowerCase();
|
||||
}
|
||||
else{
|
||||
var str = "";
|
||||
}
|
||||
this.buttons.title.caption = first_part[0] + " " + str;
|
||||
this.player.update();
|
||||
}
|
||||
}
|
||||
else{
|
||||
this.info_animation_timer = undefined;
|
||||
key_down = {};
|
||||
beforeGame();
|
||||
}
|
||||
this.player.stopped = true;
|
||||
}
|
||||
else{
|
||||
this.buttons.q.caption = "";
|
||||
this.buttons.w.caption = "";
|
||||
this.buttons.e.caption = "";
|
||||
|
||||
this.buttons.a.caption = "";
|
||||
this.buttons.s.caption = "";
|
||||
this.buttons.d.caption = "";
|
||||
|
||||
this.buttons.left.caption = "";
|
||||
this.buttons.right.caption = "";
|
||||
this.buttons.down.caption = "";
|
||||
|
||||
this.buttons.space.caption = "";
|
||||
}
|
||||
}
|
||||
checkWin(){
|
||||
if(round <= this.round_amount && player_win != 2 && bot_win != 2){
|
||||
firstState(false);
|
||||
beforeGame();
|
||||
}
|
||||
else if(!this.buttons.button2.caption){
|
||||
if(bot_win > player_win){
|
||||
this.ui.drawGameCaption(text_ctx, images.over, false, this.start_screen_delta);
|
||||
}
|
||||
else{
|
||||
this.ui.drawGameCaption(text_ctx, images.win, false, this.start_screen_delta);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function runGame(){
|
||||
game.delta++;
|
||||
if (game.delta > game.interval) {
|
||||
|
||||
game.updateAll();
|
||||
|
||||
game.delta = 0;
|
||||
}
|
||||
requestAnimationFrame(runGame);
|
||||
}
|
||||
|
||||
window.addEventListener("load", start);
|
||||
|
||||
function firstState(start = true){
|
||||
const container = document.querySelector(".container");
|
||||
|
||||
const css_string = "position: absolute;"
|
||||
canvas.style.cssText = css_string + "z-index: 0";
|
||||
intro_canvas.style.cssText = css_string + "z-index: 1";
|
||||
text_canvas.style.cssText = css_string + "z-index: 2";
|
||||
document.body.style.cssText = "display: flex; justify-content: center; height: 100vh; align-items: center";
|
||||
// document.body.style.background = "black";
|
||||
document.body.style.overflow = "hidden";
|
||||
document.body.style.margin = "0";
|
||||
|
||||
canvas.width = intro_canvas.width = text_canvas.width = images.background1.width;
|
||||
canvas.height = intro_canvas.height = text_canvas.height = images.background1.height;
|
||||
|
||||
container.style.width = canvas.width + "px";
|
||||
container.style.height = canvas.height + "px";
|
||||
|
||||
game = new Game(canvas, images, start);
|
||||
}
|
||||
|
||||
async function start(){
|
||||
images = {
|
||||
background1: await loaderPicture("./content/background1.png"),
|
||||
background2: await loaderPicture("./content/background2.png"),
|
||||
background3: await loaderPicture("./content/background3.png"),
|
||||
player: await loaderPicture("./content/player.png"),
|
||||
enemy1: await loaderPicture("./content/enemy1.png"),
|
||||
enemy2: await loaderPicture("./content/enemy2.png"),
|
||||
enemy3: await loaderPicture("./content/enemy3.png"),
|
||||
over: await loaderPicture("./content/over.png"),
|
||||
win: await loaderPicture("./content/win.png"),
|
||||
player_avatar: await loaderPicture("./content/player_avatar.png"),
|
||||
bot_avatar1: await loaderPicture("./content/bot_avatar1.png"),
|
||||
bot_avatar2: await loaderPicture("./content/bot_avatar2.png"),
|
||||
bot_avatar3: await loaderPicture("./content/bot_avatar3.png"),
|
||||
player_avatar_rage: await loaderPicture("./content/player_avatar_rage.png"),
|
||||
bot_avatar_rage: await loaderPicture("./content/bot_avatar_rage.png"),
|
||||
fight: await loaderPicture("./content/fight.png"),
|
||||
vs: await loaderPicture("./content/vs.png"),
|
||||
round1: await loaderPicture("./content/round1.png"),
|
||||
round2: await loaderPicture("./content/round2.png"),
|
||||
round3: await loaderPicture("./content/round3.png"),
|
||||
time_bar: await loaderPicture("./content/time_bar.png"),
|
||||
time_bar_mask: await loaderPicture("./content/time_bar_mask.png"),
|
||||
lock: await loaderPicture("./content/lock.png"),
|
||||
block: await loaderPicture("./content/block.png"),
|
||||
}
|
||||
window.loading_text = document.querySelector('.top-div');
|
||||
loading_text.style.display= "none";
|
||||
firstState();
|
||||
// beforeGame(); // здесь для теста
|
||||
runGame(game);
|
||||
// game.over = false; // здесь для теста
|
||||
// game.intro = false; // здесь для теста
|
||||
window.addEventListener('resize', event => {
|
||||
canvas.width = images.background1.width;
|
||||
canvas.height = images.background1.height;
|
||||
})
|
||||
document.addEventListener('keydown', event => {
|
||||
if(game.player){
|
||||
if(event.code.toLowerCase().split("key")[1]){
|
||||
var key = event.code.toLowerCase().split("key")[1]; // e.key привязан к раскладке, поэтому берем e.code.
|
||||
// Если клавиша с буквой, то забираем код и берем из него название буквы.
|
||||
// Например, для клавиши "А" код "KeyA", значит переменная index будет "A".
|
||||
}
|
||||
else{// Клавиши без букв, например, стрелки. Для них можно использовать и e.code
|
||||
var key = event.key;
|
||||
}
|
||||
|
||||
if(keyboard_pressed.indexOf(key) == -1 && (!key.split("Arrow")[1] || keyboard_pressed.length == 0) ){
|
||||
keyboard_pressed.push(key);
|
||||
}
|
||||
else{
|
||||
return;
|
||||
}
|
||||
|
||||
var index = keyboard_pressed.sort().toString();
|
||||
|
||||
if(!keyToFrame[index]){
|
||||
index = key;
|
||||
if(!keyToFrame[index]){
|
||||
// продолжаем, если есть такое действие
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const direction_hor = game.player.direction;
|
||||
|
||||
const name = keyToFrame[index].split("_");
|
||||
|
||||
const str = name[0];
|
||||
|
||||
// содержит "_Up" в конце
|
||||
const str2 = name[1];
|
||||
|
||||
// флаг для нижних ударов.
|
||||
if(index == "ArrowDown"){
|
||||
arrow_down = true;
|
||||
}
|
||||
|
||||
if(str2){
|
||||
var direction_vert = "_" + str2;
|
||||
}
|
||||
else if(arrow_down){
|
||||
var direction_vert = "_Down";
|
||||
}
|
||||
else{
|
||||
var direction_vert = "";
|
||||
}
|
||||
|
||||
if(index == "ArrowLeft" || index == "ArrowRight"){
|
||||
key_down[keyToFrame[index]] = true;
|
||||
// console.log(index)
|
||||
}
|
||||
else if(game.player[str + direction_hor + direction_vert]){
|
||||
key_down[str + direction_hor + direction_vert] = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Ниндзя код
|
||||
var k = event.code;
|
||||
var n = k.toLowerCase() == "space" ? "space" : k.toLowerCase().split("key")[1]
|
||||
|| k.toLowerCase().split("arrow")[1];
|
||||
if(n){
|
||||
btn_pressed[n] = true;
|
||||
if(game.buttons[n]){
|
||||
game.buttons[n].focus = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
document.addEventListener('keyup', event => {
|
||||
if(event.code.toLowerCase().split("key")[1]){
|
||||
var key = event.code.toLowerCase().split("key")[1]; // e.key привязан к раскладке, поэтому берем e.code.
|
||||
// Если клавиша с буквой, то забираем код и берем из него название буквы.
|
||||
// Например, для клавиши "А" код "KeyA", значит переменная index будет "A".
|
||||
}
|
||||
else{// Клавиши без букв, например, стрелки. Для них можно использовать и e.code
|
||||
var key = event.key;
|
||||
}
|
||||
|
||||
const index = key;
|
||||
|
||||
if(game.player && game.player.direction){
|
||||
const direction_hor = game.player.direction;
|
||||
|
||||
if(keyToFrame[index]){
|
||||
const name = keyToFrame[index].split("_");
|
||||
|
||||
const str = name[0];
|
||||
|
||||
// содержит "_Up" в конце
|
||||
const str2 = name[1];
|
||||
|
||||
if(str2){
|
||||
var direction_vert = "_" + str2;
|
||||
}
|
||||
else if(arrow_down){
|
||||
var direction_vert = "_Down";
|
||||
}
|
||||
else{
|
||||
var direction_vert = "";
|
||||
}
|
||||
|
||||
if(index == "ArrowLeft" || index == "ArrowRight"){
|
||||
delete key_down[keyToFrame[index]];
|
||||
}
|
||||
else if(game.player[str + direction_hor + direction_vert]){
|
||||
console.log(index, str + direction_hor + direction_vert)
|
||||
delete key_down[str + direction_hor + direction_vert];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// Ниндзя код
|
||||
var k = event.code;
|
||||
var n = k.toLowerCase() == "space" ? "space" : k.toLowerCase().split("key")[1]
|
||||
|| k.toLowerCase().split("arrow")[1];
|
||||
if(n){
|
||||
delete btn_pressed[n];
|
||||
if(game.buttons[n]){
|
||||
game.buttons[n].focus = false;
|
||||
}
|
||||
|
||||
}
|
||||
// Если не зажата кнопка "Вниз", сбрасываем индикатор зажатой клавиши
|
||||
if(index == "ArrowDown"){
|
||||
arrow_down = false;
|
||||
}
|
||||
|
||||
if(keyboard_pressed.indexOf(index) >= 0){
|
||||
keyboard_pressed.splice(keyboard_pressed.indexOf(index), 1);
|
||||
}
|
||||
});
|
||||
text_canvas.addEventListener('mousemove', event => {
|
||||
if(game.over && game.info_animation_timer == undefined){
|
||||
for(var i in game.buttons){
|
||||
var button = game.buttons[i];
|
||||
if(button && button.caption){
|
||||
if(event.offsetX > button.x * button.width
|
||||
&& event.offsetX < button.x * button.width + button.width
|
||||
&& event.offsetY > button.y * button.height
|
||||
&& event.offsetY < button.y * button.height + button.height){
|
||||
button.focus = true;
|
||||
return;
|
||||
}
|
||||
else{
|
||||
button.focus = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
text_canvas.addEventListener('mousedown', event => {
|
||||
for(var i in game.buttons){
|
||||
var button = game.buttons[i];
|
||||
if(button && button.caption){
|
||||
if(event.offsetX > button.x * button.width
|
||||
&& event.offsetX < button.x * button.width + button.width
|
||||
&& event.offsetY > button.y * button.height
|
||||
&& event.offsetY < button.y * button.height + button.height){
|
||||
button.pressed = true;
|
||||
if(!isNaN(Number(i.split("button")[1]) - 1) ){
|
||||
selected_level = Number(i.split("button")[1]) - 1;
|
||||
}
|
||||
if(i == "close"){
|
||||
game.info_animation_timer = undefined;
|
||||
key_down = {};
|
||||
beforeGame();
|
||||
return;
|
||||
}
|
||||
// Не средняя кнопка
|
||||
if(game.start_menu){
|
||||
game.info_animation_timer = 0;
|
||||
setFrameData(selected_level);
|
||||
|
||||
let player = new Player(canvas.width, canvas.height, game.images.player, 450, "player", "Игрок", undefined, undefined, undefined, 1.5)
|
||||
game.player = player;
|
||||
game.characters = {
|
||||
player: player,
|
||||
}
|
||||
}
|
||||
else{
|
||||
alert("Следующий уровень")
|
||||
game.over = true;
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else{
|
||||
button.pressed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
76
chars.js
Normal file
@ -0,0 +1,76 @@
|
||||
var letters = [];
|
||||
letters["A"] = [[0,1,1,1],[1,0,0,0,1],[1,0,0,0,1],[1,0,0,0,1],[1,1,1,1,1],[1,0,0,0,1],[1,0,0,0,1],[1,0,0,0,1]];
|
||||
letters["B"] = [[1,1,1,1],[1,0,0,0,1],[1,0,0,0,1],[1,1,1,1,0],[1,0,0,0,1],[1,0,0,0,1],[1,0,0,0,1],[1,1,1,1,0]];
|
||||
letters["C"] = [[0,1,1,1],[1,0,0,0,1],[1,0,0,0,1],[1,0,0,0,0],[1,0,0,0,0],[1,0,0,0,1],[1,0,0,0,1],[0,1,1,1]];
|
||||
letters["D"] = [[1,1,1,1],[1,0,0,0,1],[1,0,0,0,1],[1,0,0,0,1],[1,0,0,0,1],[1,0,0,0,1],[1,0,0,0,1],[1,1,1,1]];
|
||||
letters["E"] = [[1,1,1,1,1],[1,0,0,0,0],[1,0,0,0,0],[1,1,1,1,1],[1,0,0,0,0],[1,0,0,0,0],[1,0,0,0,0],[1,1,1,1,1]];
|
||||
letters["F"] = [[1,1,1,1,1],[1,0,0,0,0],[1,0,0,0,0],[1,1,1,1,0],[1,0,0,0,0],[1,0,0,0,0],[1,0,0,0,0],[1,0,0,0,0]];
|
||||
letters["G"] = [[0,1,1,1,0],[1,0,0,0,1],[1,0,0,0,0],[1,0,0,0,0],[1,0,1,1,1],[1,0,0,0,1],[1,0,0,0,1],[0,1,1,1,0]];
|
||||
letters["H"] = [[1,0,0,0,1],[1,0,0,0,1],[1,0,0,0,1],[1,1,1,1,1],[1,0,0,0,1],[1,0,0,0,1],[1,0,0,0,1],[1,0,0,0,1]];
|
||||
letters["I"] = [[1,1,1,1,1],[0,0,1,0,0],[0,0,1,0,0],[0,0,1,0,0],[0,0,1,0,0],[0,0,1,0,0],[0,0,1,0,0],[1,1,1,1,1]];
|
||||
letters["J"] = [[1,1,1,1,1],[0,0,1,0,0],[0,0,1,0,0],[0,0,1,0,0],[0,0,1,0,0],[0,0,1,0,0],[0,0,1,0,0],[1,1,1,0,0]];
|
||||
letters["K"] = [[1,0,0,0,1],[1,0,0,1,0],[1,0,0,1,0],[1,1,1,0,0],[1,0,0,1,0],[1,0,0,0,1],[1,0,0,0,1],[1,0,0,0,1]];
|
||||
letters["L"] = [[1,0,0,0,0],[1,0,0,0,0],[1,0,0,0,0],[1,0,0,0,0],[1,0,0,0,0],[1,0,0,0,0],[1,0,0,0,0],[1,1,1,1,1]];
|
||||
letters["M"] = [[1,0,0,0,1],[1,0,0,0,1],[1,1,0,1,1],[1,0,1,0,1],[1,0,0,0,1],[1,0,0,0,1],[1,0,0,0,1],[1,0,0,0,1]];
|
||||
letters["N"] = [[1,0,0,0,1],[1,1,0,0,1],[1,0,1,0,1],[1,0,0,1,1],[1,0,0,0,1],[1,0,0,0,1],[1,0,0,0,1],[1,0,0,0,1]];
|
||||
letters["O"] = [[0,1,1,1],[1,0,0,0,1,0,0,0],[1,0,0,0,1,0,0],[1,0,0,0,1,0,0,0],[1,0,0,0,1,0,0,0],[1,0,0,0,1,0,0,0],[1,0,0,0,1],[0,1,1,1]];
|
||||
letters["P"] = [[1,1,1,1,0],[1,0,0,0,1],[1,0,0,0,1],[1,0,0,0,1],[1,1,1,1,0],[1,0,0,0,0],[1,0,0,0,0],[1,0,0,0,0]];
|
||||
letters["Q"] = [[0,1,1,1,0],[1,0,0,0,1],[1,0,0,0,1],[1,0,0,0,1],[1,0,0,0,1],[1,0,1,0,1],[1,0,0,1,0],[0,1,1,1,1]];
|
||||
letters["R"] = [[1,1,1,1,0],[1,0,0,0,1],[1,0,0,0,1],[1,0,0,0,1],[1,1,1,1,0],[1,0,0,1,0],[1,0,0,0,1],[1,0,0,0,1]];
|
||||
letters["S"] = [[0,1,1,1,0],[1,0,0,0,1],[1,0,0,0,0],[1,1,0,0,0],[0,0,1,1,1],[0,0,0,0,1],[1,0,0,0,1],[0,1,1,1,0]];
|
||||
letters["T"] = [[1,1,1,1,1],[0,0,1,0,0,null,0,null,null,null,0],[0,0,1,0,0,null,0,0,null,0,0],[0,0,1,0,0,null,0,null,0,null,0],[0,0,1,0,0,null,0],[0,0,1,0,0,null,0],[0,0,1,0,0,null,0],[0,0,1,0,0,null,0]];
|
||||
letters["U"] = [[1,0,0,0,1],[1,0,0,0,1],[1,0,0,0,1],[1,0,0,0,1],[1,0,0,0,1],[1,0,0,0,1],[1,0,0,0,1],[0,1,1,1,0]];
|
||||
letters["V"] = [[1,0,0,0,1],[1,0,0,0,1],[1,0,0,0,1],[1,0,0,0,1],[1,0,0,0,1],[1,0,0,0,1],[0,1,0,1,0],[0,0,1,0,0]];
|
||||
letters["W"] = [[1,0,0,0,1],[1,0,0,0,1],[1,0,0,0,1],[1,0,0,0,1],[1,0,1,0,1],[1,1,0,1,1],[1,0,0,0,1],[1,0,0,0,1]];
|
||||
letters["X"] = [[1,0,0,0,1],[1,0,0,0,1],[0,1,0,1,0],[0,0,1,0,0],[0,1,0,1,0],[1,0,0,0,1],[1,0,0,0,1],[1,0,0,0,1]];
|
||||
letters["Y"] = [[1,0,0,0,1],[1,0,0,0,1],[1,0,0,0,1],[0,1,0,1,0],[0,0,1,0,0],[0,0,1,0,0],[0,0,1,0,0],[0,0,1,0,0]];
|
||||
letters["Z"] = [[1,1,1,1,1],[1,0,0,0,1],[0,0,0,1,0],[0,0,1,0,0],[0,1,0,0,0],[1,0,0,0,0],[1,0,0,0,1],[1,1,1,1,1]];
|
||||
letters[" "] = [[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0]];
|
||||
letters["a"] = [[0,0,0,0,0],[0,1,1,1,0,0,0,0,0,0,0],[1,0,0,0,1,0,0,0,0,0,0],[0,0,0,0,1,0,0,0,0,0,0],[0,1,1,1,1,0,0],[1,0,0,0,1,0,0],[1,0,0,0,1,0,0],[0,1,1,1,1,0,0]];
|
||||
letters["b"] = [[0,0,0,0,0],[0,1,1,1,0,0,0,0,0,0,0],[1,0,0,0,1,0,0,0,0,0,0],[1,0,0,0,1,0,0,0,0,0,0],[1,1,1,1,0,0,0],[1,0,0,0,1,0,0],[1,0,0,0,1,0,0],[1,1,1,1,0,0,0]];
|
||||
letters["c"] = [[0,0,0,0,0],[0,1,1,1,0,0,0,0,0,0,0],[1,0,0,0,1,0,0,0,0,0,0],[1,0,0,0,0,0,0,0,0,0,0],[1,0,0,0,0,0,0],[1,0,0,0,0,0,0],[1,0,0,0,1,0,0],[0,1,1,1,0,0,0]];
|
||||
letters["d"] = [[0,0,0,0,1],[0,0,0,0,1,0,0,0,0,0,0],[0,0,0,0,1,0,0,0,0,0,0],[1,1,1,1,1,0,0,0,0,0,0],[1,0,0,0,1,0,0],[1,0,0,0,1,0,0],[1,0,0,0,1,0,0],[1,1,1,1,1,0,0]];
|
||||
letters["e"] = [[0,0,0,0,0],[0,1,1,1,0,0,0,0,0,0,0],[1,0,0,0,1,0,0,0,0,0,0],[1,0,0,0,1,0,0,0,0,0,0],[1,1,1,1,1,0,0],[1,0,0,0,0,0,0],[1,0,0,0,0,0,0],[0,1,1,1,0,0,0]];
|
||||
letters["f"] = [[0,0,0,0,0],[0,1,1,1,0,0,0,0,0,0,0],[1,0,0,0,1,0,0,0,0,0,0],[1,0,0,0,0,0,0,0,0,0,0],[1,0,0,0,0,0,0],[1,1,1,1,0,0,0],[1,0,0,0,0,0,0],[1,0,0,0,0,0,0]];
|
||||
letters["g"] = [[0,0,0,0,0],[0,1,1,1,0,0,0,0,0,0,0],[1,0,0,0,1,0,0,0,0,0,0],[1,0,0,0,1,0,0,0,0,0,0],[1,0,0,1,1,0,0],[0,1,1,0,1,0,0],[0,0,0,0,1,0,0],[0,1,1,1,1,0,0]];
|
||||
letters["h"] = [[1,0,0,0,0],[1,0,0,0,0,0,0,0,0,0,0],[1,0,0,0,0,0,0,0,0,0,0],[1,1,1,1,0,0,0,0,0,0,0],[1,0,0,0,1,0,0],[1,0,0,0,1,0,0],[1,0,0,0,1,0,0],[1,0,0,0,1,0,0]];
|
||||
letters["i"] = [[0,0,1,0,0],[0,0,0,0,0,0,0,0,0,0,0],[0,0,1,0,0,0,0,0,0,0,0],[0,0,1,0,0,0,0,0,0,0,0],[0,0,1,0,0,0,0],[0,0,1,0,0,0,0],[0,0,1,0,0,0,0],[1,1,1,1,1,0,0]];
|
||||
letters["j"] = [[0,0,1,0,0],[0,0,0,0,0,0,0,0,0,0,0],[0,0,1,0,0,0,0,0,0,0,0],[0,0,1,0,0,0,0,0,0,0,0],[0,0,1,0,0,0,0],[0,0,1,0,0,0,0],[0,0,1,0,0,0,0],[1,1,1,0,0,0,0]];
|
||||
letters["k"] = [[1,0,0,0,0],[1,0,0,0,1,0,0,0,0,0,0],[1,0,0,1,0,0,0,0,0,0,0],[1,0,1,0,0,0,0,0,0,0,0],[1,1,1,1,0,0,0],[1,0,0,0,1,0,0],[1,0,0,0,1,0,0],[1,0,0,0,1,0,0]];
|
||||
letters["l"] = [[0,1,1,0,0],[0,0,1,0,0,0,0,0,0,0,0],[0,0,1,0,0,0,0,0,0,0,0],[0,0,1,0,0,0,0,0,0,0,0],[0,0,1,0,0,0,0],[0,0,1,0,0,0,0],[0,0,1,0,0,0,0],[1,1,1,1,1,0,0]];
|
||||
letters["m"] = [[0,0,0,0,0],[1,1,1,1,0,0,0,0,0,0,0],[1,0,1,0,1,0,0,0,0,0,0],[1,0,1,0,1,0,0,0,0,0,0],[1,0,1,0,1,0,0],[1,0,1,0,1,0,0],[1,0,1,0,1,0,0],[1,0,1,0,1,0,0]];
|
||||
letters["n"] = [[0,0,0,0,0],[1,1,1,1,0,0,0,0,0,0,0],[1,0,0,0,1,0,0,0,0,0,0],[1,0,0,0,1,0,0,0,0,0,0],[1,0,0,0,1,0,0],[1,0,0,0,1,0,0],[1,0,0,0,1,0,0],[1,0,0,0,1,0,0]];
|
||||
letters["o"] = [[0,0,0,0,0],[0,1,1,1,0,0,0,0,0,0,0],[1,0,0,0,1,0,0,0,0,0,0],[1,0,0,0,1,0,0,0,0,0,0],[1,0,0,0,1,0,0],[1,0,0,0,1,0,0],[1,0,0,0,1,0,0],[0,1,1,1,0,0,0]];
|
||||
letters["p"] = [[0,0,0,0,0],[0,1,1,1,0,0,0,0,0,0,0],[1,0,0,0,1,0,0,0,0,0,0],[1,0,0,0,1,0,0,0,0,0,0],[1,0,0,0,1,0,0],[1,1,1,1,0,0,0],[1,0,0,0,0,0,0],[1,0,0,0,0,0,0]];
|
||||
letters["q"] = [[0,0,0,0,0],[0,1,1,1,0,0,0,0,0,0,0],[1,0,0,0,1,0,0,0,0,0,0],[1,0,0,0,1,0,0,0,0,0,0],[1,0,0,0,1,0,0],[0,1,1,1,1,0,0],[0,0,0,0,1,0,0],[0,0,0,0,1,0,0]];
|
||||
letters["r"] = [[0,0,0,0,0],[1,0,1,1,0,0,0,0,0,0,0],[1,1,0,0,1,0,0,0,0,0,0],[1,0,0,0,1,0,0,0,0,0,0],[1,0,0,0,0,0,0],[1,0,0,0,0,0,0],[1,0,0,0,0,0,0],[1,0,0,0,0,0,0]];
|
||||
letters["s"] = [[0,0,0,0,0],[0,1,1,1,0,0,0,0,0,0,0],[1,0,0,0,1,0,0,0,0,0,0],[1,1,0,0,0,0,0,0,0,0,0],[0,0,1,1,0,0,0],[0,0,0,0,1,0,0],[1,0,0,0,1,0,0],[0,1,1,1,0,0,0]];
|
||||
letters["t"] = [[0,0,1,0,0],[1,1,1,1,1,0,0,0,0,0,0],[0,0,1,0,0,0,0,0,0,0,0],[0,0,1,0,0,0,0,0,0,0,0],[0,0,1,0,0,0,0],[0,0,1,0,0,0,0],[0,0,1,0,0,0,0],[0,0,1,1,0,0,0]];
|
||||
letters["u"] = [[0,0,0,0,0],[1,0,0,0,1,0,0,0,0,0,0],[1,0,0,0,1,0,0,0,0,0,0],[1,0,0,0,1,0,0,0,0,0,0],[1,0,0,0,1,0,0],[1,0,0,0,1,0,0],[1,0,0,1,1,0,0],[0,1,1,0,1,0,0]];
|
||||
letters["v"] = [[0,0,0,0,0],[1,0,0,0,1,0,0,0,0,0,0],[1,0,0,0,1,0,0,0,0,0,0],[1,0,0,0,1,0,0,0,0,0,0],[1,0,0,0,1,0,0],[1,0,0,1,0,0,0],[0,1,1,0,0,0,0],[0,1,0,0,0,0,0]];
|
||||
letters["w"] = [[0,0,0,0,0],[1,0,0,0,1,0,0,0,0,0,0],[1,0,0,0,1,0,0,0,0,0,0],[1,0,0,0,1,0,0,0,0,0,0],[1,0,0,0,1,0,0],[1,0,0,0,1,0,0],[1,0,1,0,1,0,0],[0,1,0,1,0,0,0]];
|
||||
letters["x"] = [[0,0,0,0,0],[1,0,0,0,1,0,0,0,0,0,0],[0,1,0,1,0,0,0,0,0,0,0],[0,0,1,0,0,0,0,0,0,0,0],[0,1,0,1,0,0,0],[1,0,0,0,1,0,0],[1,0,0,0,1,0,0],[0,0,0,0,0,0,0]];
|
||||
letters["y"] = [[0,0,0,0,0],[1,0,0,0,1,0,0,0,0,0,0],[1,0,0,0,1,0,0,0,0,0,0],[0,1,1,1,1,0,0,0,0,0,0],[0,0,0,0,1,0,0],[0,0,0,1,1,0,0],[0,1,1,0,0,0,0],[0,0,0,0,0,0,0]];
|
||||
letters["z"] = [[0,0,0,0,0],[1,1,1,1,1,0,0,0,0,0,0],[1,0,0,0,1,0,0,0,0,0,0],[0,0,0,1,0,0,0,0,0,0,0],[0,0,1,0,0,0,0],[0,1,0,0,1,0,0],[1,1,1,1,1,0,0],[0,0,0,0,0,0,0]];
|
||||
letters["-"] = [[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[1,1,1,1,1],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0]];
|
||||
|
||||
letters["("] = [[0,0,1,0,0],[0,1,0,0,0],[0,1,0,0,0],[0,1,0,0,0],[0,1,0,0,0],[0,1,0,0,0],[0,1,0,0,0],[0,0,1,0,0]];
|
||||
letters[")"] = [[0,0,1,0,0],[0,0,0,1,0],[0,0,0,1,0],[0,0,0,1,0],[0,0,0,1,0],[0,0,0,1,0],[0,0,0,1,0],[0,0,1,0,0]];
|
||||
letters["."] = [[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,1,0,0,0]];
|
||||
letters[","] = [[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,1,0,0,0],[0,1,0,0,0]];
|
||||
letters[":"] = [[0,0,0,0,0],[1,0,0,0,0,0,0,0,0,0,0],[1,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[1,0,0,0,0,0,0],[1,0,0,0,0,0,0]];
|
||||
letters["!"] = [[1,0,0,0,0],[1,0,0,0,0,0,0,0,0,0,0],[1,0,0,0,0,0,0,0,0,0,0],[1,0,0,0,0,0,0,0,0,0,0],[1,0,0,0,0,0,0],[1,0,0,0,0,0,0],[0,0,0,0,0,0,0],[1,0,0,0,0,0,0]];
|
||||
letters["?"] = [[0,1,1,1,0],[1,0,0,0,1,0,0,0,0,0,0],[1,0,0,0,1,0,0,0,0,0,0],[0,0,0,1,0,0,0,0,0,0,0],[0,0,1,0,0,0,0],[0,0,0,0,0,0,0],[0,0,1,0,0,0,0],[0,0,0,0,0,0,0]];
|
||||
letters["1"] = [[0,0,1,0,0],[0,1,1,0,0],[1,0,1,0,0],[0,0,1,0,0],[0,0,1,0,0],[0,0,1,0,0],[0,0,1,0,0],[1,1,1,1,1]];
|
||||
letters["2"] = [[0,1,1,1,0],[1,0,0,0,1],[1,0,0,0,1],[0,0,0,1,0],[0,0,1,0,0],[0,1,0,0,0],[1,0,0,0,0],[1,1,1,1,1]];
|
||||
letters["3"] = [[0,1,1,1,0],[1,0,0,0,1],[0,0,0,0,1],[0,0,0,1,0],[0,0,1,0,1],[0,0,0,0,1],[1,0,0,0,1],[0,1,1,1,0]];
|
||||
letters["4"] = [[0,0,0,1,1],[0,0,1,0,1],[0,1,0,0,1],[1,0,0,0,1],[1,1,1,1,1],[0,0,0,0,1],[0,0,0,0,1],[0,0,0,0,1]];
|
||||
letters["5"] = [[1,1,1,1,1],[1,0,0,0,0],[1,0,0,0,0],[1,1,1,1,0],[0,0,0,0,1],[0,0,0,0,1],[1,0,0,0,1],[0,1,1,1,0]];
|
||||
letters["6"] = [[0,1,1,1,0],[1,0,0,0,1],[1,0,0,0,0],[1,1,1,1,0],[1,0,0,0,1],[1,0,0,0,1],[1,0,0,0,1],[0,1,1,1,0]];
|
||||
letters["7"] = [[1,1,1,1,1],[0,0,0,0,1],[0,0,0,1,0],[0,0,1,0,0],[0,1,0,0,0],[1,0,0,0,0],[1,0,0,0,0],[1,0,0,0,0]];
|
||||
letters["8"] = [[0,1,1,1,0],[1,0,0,0,1],[1,0,0,0,1],[0,1,1,1,0],[1,0,0,0,1],[1,0,0,0,1],[1,0,0,0,1],[0,1,1,1,0]];
|
||||
letters["9"] = [[0,1,1,1,0],[1,0,0,0,1],[1,0,0,0,1],[1,0,0,0,1],[0,1,1,1,1],[0,0,0,0,1],[1,0,0,0,1],[0,1,1,1,0]];
|
||||
letters["0"] = [[0,1,1,1,0],[1,0,0,0,1],[1,0,0,0,1],[1,0,0,0,1],[1,0,0,0,1],[1,0,0,0,1],[1,0,0,0,1],[0,1,1,1,0]];
|
||||
letters["<"] = [[0,0,0,1,0],[0,0,1,0,0],[0,1,0,0,0],[1,0,0,0,0],[1,0,0,0,0],[0,1,0,0,0],[0,0,1,0,0],[0,0,0,1,0]];
|
||||
letters[">"] = [[0,1,0,0,0],[0,0,1,0,0],[0,0,0,1,0],[0,0,0,0,1],[0,0,0,0,1],[0,0,0,1,0],[0,0,1,0,0],[0,1,0,0,0]];
|
||||
letters["|"] = [[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[1,0,0,0,1],[1,0,0,0,1],[0,1,0,1,0],[0,1,0,1,0],[0,0,1,0,0]];
|
After Width: | Height: | Size: 7.7 KiB |
After Width: | Height: | Size: 7.7 KiB |
After Width: | Height: | Size: 7.7 KiB |
After Width: | Height: | Size: 7.7 KiB |
After Width: | Height: | Size: 7.7 KiB |
BIN
content/background1.png
Normal file
After Width: | Height: | Size: 342 KiB |
BIN
content/background2.png
Normal file
After Width: | Height: | Size: 356 KiB |
BIN
content/background3.png
Normal file
After Width: | Height: | Size: 289 KiB |
BIN
content/block.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
content/bot_avatar1.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
content/bot_avatar2.png
Normal file
After Width: | Height: | Size: 37 KiB |
BIN
content/bot_avatar3.png
Normal file
After Width: | Height: | Size: 31 KiB |
BIN
content/bot_avatar_rage.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
content/enemy1.png
Normal file
After Width: | Height: | Size: 1.1 MiB |
BIN
content/enemy2.png
Normal file
After Width: | Height: | Size: 1007 KiB |
BIN
content/enemy3.png
Normal file
After Width: | Height: | Size: 1.1 MiB |
BIN
content/fight.png
Normal file
After Width: | Height: | Size: 36 KiB |
BIN
content/lock.png
Normal file
After Width: | Height: | Size: 7.0 KiB |
BIN
content/over.png
Normal file
After Width: | Height: | Size: 105 KiB |
BIN
content/player.png
Normal file
After Width: | Height: | Size: 952 KiB |
BIN
content/player_avatar.png
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
content/player_avatar_rage.png
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
content/round1.png
Normal file
After Width: | Height: | Size: 37 KiB |
BIN
content/round2.png
Normal file
After Width: | Height: | Size: 38 KiB |
BIN
content/round3.png
Normal file
After Width: | Height: | Size: 37 KiB |
BIN
content/time_bar.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
content/time_bar_mask.png
Normal file
After Width: | Height: | Size: 821 B |
BIN
content/vs.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
content/win.png
Normal file
After Width: | Height: | Size: 57 KiB |
87
enemy.js
Normal file
@ -0,0 +1,87 @@
|
||||
class Enemy extends Player{
|
||||
constructor(w, h, image, dx, type, name, frameWidth, frameHeight, frameSpeed, size){
|
||||
super(w, h, image, dx, type, name, frameWidth, frameHeight, frameSpeed, size);
|
||||
}
|
||||
reaction(nemesis_action_params){
|
||||
// Если противник встал, то мы тоже встаем
|
||||
if(this.nemesis && this.nemesis.currentAction == "crouch" + this.nemesis.direction + "_Up"){
|
||||
this.currentFrame = 0;
|
||||
this.crouch = false;
|
||||
}
|
||||
// Если предыдущая анимация завершилась или мы присели (тогда
|
||||
// текущий кадр будет равен последнему кадру анимации)
|
||||
if(this.currentFrame == 0 || frame_data[this.name][this.currentAction].no_return
|
||||
&& this.currentFrame >= frame_data[this.name][this.currentAction].end - frame_data[this.name][this.currentAction].start - 1){
|
||||
this.idleCount = 0;
|
||||
if( "reaction" in nemesis_action_params){
|
||||
const rand = getRand(1, 100); // число для случайного ответа
|
||||
for(var obj of nemesis_action_params.reaction){
|
||||
const range = obj.chance.split("-");
|
||||
// если число в диапазоне
|
||||
if(rand >= range[0] && rand < range[1]){
|
||||
// В это условие мы попадаем в двух случаях: Если идет бой
|
||||
// или мы приблизились на расстояние, когда бот начинает подбегать к нам.
|
||||
// Здесь мы вызываем реакцию из объекта nemesis_action_params
|
||||
// Реакция это имя действия ("walk", "punch", "stand") плюс направление
|
||||
// по горизонтали ("_Left" или "_Right"), плюс направление по вертикали —
|
||||
// "Up", "Down", или "". Направление по вертикали это либо имя реакции плюс
|
||||
// вертикальное направление удара врага (например, враг бьет сверху kick_Left_Up,
|
||||
// тогда наша рекация будет "block" + "_Right" + "_Up"), либо имя реакции может отсылать
|
||||
// к действию, которое само содержит в названии "_Up", тогда так же добавляем его к имени/
|
||||
// Либо это удары "punch", "block", "crouch" — тогда добавляем третий параметр
|
||||
// после "_" в названии удара противника (то есть верхним ударам соотвествуют верхние,
|
||||
// средним средние, нижним нижние)
|
||||
if(this.nemesis){
|
||||
const nemesis_action = this.nemesis.currentAction;
|
||||
var nemesis_action_name = this.nemesis.currentAction.split("_")[0];
|
||||
var nemesis_action_vert_direct = this.nemesis.currentAction.split("_")[2];
|
||||
}
|
||||
if( (obj.name == "punch" || obj.name == "block" || obj.name == "crouch")
|
||||
&& this.nemesis && nemesis_action_vert_direct){
|
||||
if(obj.name != "punch"){
|
||||
var vert_direct = "_" + nemesis_action_vert_direct;
|
||||
}
|
||||
else{
|
||||
var vert_direct = "";
|
||||
}
|
||||
}
|
||||
// у kick только верхняя она удара
|
||||
else if(obj.name == "kick"){
|
||||
var vert_direct = "_Up" ;
|
||||
}
|
||||
else{
|
||||
var vert_direct = "";
|
||||
}
|
||||
|
||||
const action_name = obj.name + this.direction + vert_direct;
|
||||
// Если бот присел и ничего не делает (то есть action_name == "crouch"),
|
||||
// то doAction не вызываем,
|
||||
// вызывается, если он производит действие — блок, удар и тп
|
||||
|
||||
const condition = !this.crouch || action_name != "crouch" + this.direction + "_Down";
|
||||
if(condition){
|
||||
this.doAction(action_name, this.crouch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
collision(){
|
||||
super.collision();
|
||||
if(this.potential_nemesis && !this.potential_nemesis.dy){
|
||||
if(!this.stopped){
|
||||
// подбегаем, если дистанция между противниками меньше нужной величины
|
||||
// или бездействие больше определенной величины (увеличивается в update класса Player)
|
||||
if(this.collision_distance > this.min_distance && (this.collision_distance < this.max_distance || this.idleCount > this.maxIdle) ){
|
||||
// если игрок на дистанции больше и меньше определенного значения,
|
||||
// то бот реагирует как на действие walk в его направлении
|
||||
if(!this.complex){
|
||||
this.reaction(frame_data[this.name]["walk" + this.potential_nemesis.direction]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
221
frame_data.js
Normal file
@ -0,0 +1,221 @@
|
||||
const timing = {
|
||||
player: {
|
||||
value: {
|
||||
punch_Right: {start: 0, end: 9},
|
||||
punch_Left: {start: 10, end: 18},
|
||||
punch_Right_Down: {start: 105, end: 112},
|
||||
punch_Left_Down: {start: 113, end: 120},
|
||||
block_Right: {start: 19, end: 27},
|
||||
block_Left: {start: 28, end: 36},
|
||||
block_Right_Up: {start: 37, end: 44},
|
||||
block_Left_Up: {start: 45, end: 54},
|
||||
block_Right_Down: {start: 126, end: 133},
|
||||
block_Left_Down: {start: 134, end: 146},
|
||||
stand_Left: {start: 55, end: 60},
|
||||
stand_Right: {start: 61, end: 67},
|
||||
jump_Right: {start: 68, end: 76 },
|
||||
jump_Left: {start: 77, end: 84 },
|
||||
crouch_Right_Down: {start: 85, end: 90},
|
||||
crouch_Right_Up: {start: 91, end: 94},
|
||||
crouch_Left_Down: {start: 95, end: 100},
|
||||
crouch_Left_Up: {start: 101, end: 104},
|
||||
walk_Right: {start: 146, end: 154},
|
||||
walk_Left: {start: 155, end: 162},
|
||||
kick_Right_Up: {start: 163, end: 167},
|
||||
kick_Left_Up: {start: 168, end: 172},
|
||||
},
|
||||
size: {
|
||||
w: 224,
|
||||
h: 214
|
||||
}
|
||||
},
|
||||
bar_enemy_timing:{
|
||||
value: {
|
||||
punch_Right: {start: 261, end: 276},
|
||||
punch_Left: {start: 15, end: 30},
|
||||
punch_Right_Down: {start: 181, end: 195, active: {start:192, end:195} },
|
||||
punch_Left_Down: {start: 167, end: 180, active: {start:176, end:179} },
|
||||
block_Right: {start: 254, end: 259, speed: 1},
|
||||
block_Left: {start: 248, end: 253, speed: 1},
|
||||
block_Right_Up: {start: 73, end: 85},
|
||||
block_Left_Up: {start: 49, end: 57},
|
||||
block_Right_Down: {start: 243, end: 247, speed: 1},
|
||||
block_Left_Down: {start: 238, end: 242, speed: 1},
|
||||
stand_Left: {start: 0, end: 6, speed: 1},
|
||||
stand_Right: {start: 7, end: 13, speed: 1},
|
||||
jump_Right: {start: 120, end: 131 },
|
||||
jump_Left: {start: 97, end: 108 },
|
||||
crouch_Right_Down: {start: 150, end: 165},
|
||||
crouch_Right_Up: {start: 162, end: 155},
|
||||
crouch_Left_Down: {start: 133, end: 148},
|
||||
crouch_Left_Up: {start: 145, end: 140},
|
||||
walk_Right: {start: 223, end: 237},
|
||||
walk_Left: {start: 208, end: 222},
|
||||
kick_Right_Up: {start: 203, end: 208},
|
||||
kick_Left_Up: {start: 197, end: 202}
|
||||
},
|
||||
size: {
|
||||
w: 148,
|
||||
h: 214
|
||||
},
|
||||
speed: 2
|
||||
},
|
||||
car_salon_enemy_timing:{
|
||||
value: {
|
||||
punch_Right: {start: 159, end: 166},
|
||||
punch_Left: {start: 8, end: 15},
|
||||
punch_Right_Down: {start: 64, end: 70},
|
||||
punch_Left_Down: {start: 134, end: 140},
|
||||
block_Right: {start: 0, end: 7},
|
||||
block_Left: {start: 39, end: 45},
|
||||
block_Right_Up: {start: 18, end: 22},
|
||||
block_Left_Up: {start: 26, end: 30},
|
||||
block_Right_Down: {start: 125, end: 133},
|
||||
block_Left_Down: {start: 149, end: 157},
|
||||
stand_Left: {start: 56, end: 63},
|
||||
stand_Right: {start: 47, end: 55},
|
||||
jump_Right: {start: 80, end: 86 },
|
||||
jump_Left: {start: 87, end: 93 },
|
||||
crouch_Right_Down: {start: 101, end: 107},
|
||||
crouch_Right_Up: {start: 106, end: 109},
|
||||
crouch_Left_Down: {start: 169, end: 172},
|
||||
crouch_Left_Up: {start: 173, end: 174},
|
||||
walk_Right: {start: 117, end: 124},
|
||||
walk_Left: {start: 141, end: 148},
|
||||
kick_Right_Up: {start: 109, end: 116},
|
||||
kick_Left_Up: {start: 93, end: 100},
|
||||
},
|
||||
size: {
|
||||
// w: 224,
|
||||
// h: 214
|
||||
}
|
||||
},
|
||||
gg_cabinet_enemy_timing:{
|
||||
value: {
|
||||
punch_Right: {start: 9, end: 17},
|
||||
punch_Left: {start: 0, end: 8},
|
||||
punch_Right_Down: {start: 124, end: 129},
|
||||
punch_Left_Down: {start: 118, end: 123},
|
||||
block_Right: {start: 26, end: 33},
|
||||
block_Left: {start: 18, end: 25},
|
||||
block_Right_Up: {start: 42, end: 49},
|
||||
block_Left_Up: {start: 34, end: 41},
|
||||
block_Right_Down: {start: 154, end: 161},
|
||||
block_Left_Down: {start: 130, end: 137},
|
||||
stand_Left: {start: 50, end: 57},
|
||||
stand_Right: {start: 58, end: 65},
|
||||
jump_Right: {start: 74, end: 81 },
|
||||
jump_Left: {start: 66, end: 73 },
|
||||
crouch_Right_Down: {start: 110, end: 114},
|
||||
crouch_Right_Up: {start: 115, end: 117},
|
||||
crouch_Left_Down: {start: 98, end: 104},
|
||||
crouch_Left_Up: {start: 105, end: 109},
|
||||
walk_Right: {start: 146, end: 153},
|
||||
walk_Left: {start: 138, end: 145},
|
||||
kick_Right_Up: {start: 90, end: 97},
|
||||
kick_Left_Up: {start: 82, end: 89},
|
||||
},
|
||||
size: {
|
||||
// w: 224,
|
||||
// h: 214
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// reaction — ответная рекация бота на наши действия
|
||||
// chance — вероятность того, что это действие будет выбрано ботом
|
||||
// name — имя реакции, отсылающее к названию действия (метода классов Player и Enemy)
|
||||
// damage — урон
|
||||
// resist — уменьшение урона
|
||||
// complex — сложное действие, состоящее из двух или более. У него нет параметров,
|
||||
// оно просто отсылает к методу классов Player и Enemy
|
||||
// start и end — номера кадров начала и конца анимации
|
||||
// once — действие, выванное единожды за одно нажатие клавиши (если зажали кнопку и не отпускаем),
|
||||
// например walk вызывается постоянно, пока зажата клавиша, а удар при зажатой клавише
|
||||
// вызовется только один раз — чтобы вызвать его еще раз надо отпустить клавишу и снова нажать
|
||||
// no_return — значит, мы не возвращаемся в стойку после действия once. Например, мы присели crouch
|
||||
// active — активные кадры, когда персонаж способен наносить урон, если не указано,
|
||||
// то активна середина анимации
|
||||
// cool_down — число ударов, после которых наступит заморозка
|
||||
|
||||
class FrameData{
|
||||
constructor(timing){
|
||||
this.timing = timing;
|
||||
this.punch_Right = {once: true, start: undefined, end: undefined,
|
||||
damage: 0.5,
|
||||
reaction: [{name: "block", chance: "0-50"}, {name: "punch", chance: "50-80"}, {name: "stand", chance: "80-100"}]
|
||||
};
|
||||
this.punch_Left = {once: true, start: undefined, end: undefined,
|
||||
damage: 0.5,
|
||||
reaction: [{name: "block", chance: "0-50"}, {name: "punch", chance: "50-80"}, {name: "stand", chance: "80-100"}]
|
||||
};
|
||||
this.punch_Right_Down = {once: true, no_return: true, start: undefined, end: undefined,
|
||||
damage: 0.5,
|
||||
reaction: [{name: "block", chance: "0-50"}, {name: "punch", chance: "50-80"}, {name: "crouch", chance: "80-100"}]
|
||||
};
|
||||
this.punch_Left_Down = {once: true, no_return: true, start: undefined, end: undefined,
|
||||
damage: 0.5,
|
||||
reaction: [{name: "block", chance: "0-50"}, {name: "punch", chance: "50-80"}, {name: "crouch", chance: "80-100"}]
|
||||
};
|
||||
this.block_Right = { start: undefined, end: undefined, resist: 1, active: {start:20, end:24},
|
||||
reaction: [{name: "punch", chance: "00-80"}, {name: "stand", chance: "80-100"}]
|
||||
};
|
||||
this.block_Left = { start: undefined, end: undefined, resist: 1 , active: {start:29, end:33},
|
||||
reaction: [{name: "punch", chance: "00-80"}, {name: "stand", chance: "80-100"}]
|
||||
};
|
||||
this.block_Right_Up = { start: undefined, end: undefined, resist: 1, active: {start:39, end:42},
|
||||
reaction: [{name: "punch", chance: "00-80"}, {name: "stand", chance: "80-100"}]
|
||||
};
|
||||
this.block_Left_Up = { start: undefined, end: undefined, resist: 1, active: {start:48, end:52},
|
||||
reaction: [{name: "punch", chance: "00-80"}, {name: "stand", chance: "80-100"}]
|
||||
};
|
||||
this.block_Right_Down = { start: undefined, end: undefined, resist: 1, active: {start:39, end:42},
|
||||
reaction: [{name: "punch", chance: "00-80"}, {name: "stand", chance: "80-100"}]
|
||||
};
|
||||
this.block_Left_Down = { start: undefined, end: undefined, resist: 1, active: {start:48, end:52},
|
||||
reaction: [{name: "punch", chance: "00-80"}, {name: "stand", chance: "80-100"}]
|
||||
};
|
||||
this.stand_Left = { start: undefined, end: undefined,
|
||||
reaction: [{name: "punch", chance: "0-60"}, {name: "kick", chance: "60-80"}, {name: "stand", chance: "80-90"}, {name: "walkAway", chance: "90-100"}]
|
||||
};
|
||||
this.stand_Right = { start: undefined, end: undefined,
|
||||
reaction: [{name: "punch", chance: "0-60"}, {name: "kick", chance: "60-80"}, {name: "stand", chance: "80-90"}, {name: "walkAway", chance: "90-100"}]
|
||||
};
|
||||
this.jump_Right = { start: undefined, end: 76,
|
||||
reaction: [{name: "jumpAsidePunch", chance: "0-50"}, {name: "stand", chance: "0-50"}]
|
||||
},
|
||||
this.jump_Left = { start: undefined, end: 84,
|
||||
reaction: [{name: "jumpAsidePunch", chance: "0-50"}, {name: "stand", chance: "0-50"}]
|
||||
},
|
||||
this.crouch_Right_Down = {start: undefined, end: undefined, resist: 0.2, once: true , no_return: true,
|
||||
reaction: [{name: "crouch", chance: "0-50"}, {name: "punch", chance: "50-100"}]
|
||||
};
|
||||
this.crouch_Right_Up = { start: undefined, end: 94 , once: true , no_return: true,
|
||||
reaction: [{name: "crouch", chance: "0-100"}]
|
||||
};
|
||||
this.crouch_Left_Down = {start: undefined, end: undefined, resist: 0.2, once: true, no_return: true,
|
||||
reaction: [{name: "crouch", chance: "0-50"}, {name: "punch", chance: "50-100"}]
|
||||
};
|
||||
this.crouch_Left_Up = { start: undefined, end: 104 , once: true, no_return: true,
|
||||
reaction: [{name: "crouch", chance: "0-100"}]
|
||||
};
|
||||
this.walk_Right = { start: undefined, end: undefined,
|
||||
reaction: [{name: "walk", chance: "0-50"}, {name: "jumpAsidePunch", chance: "50-60"}, {name: "stand", chance: "60-80"}, {name: "jumpAside", chance: "80-100"}]
|
||||
};
|
||||
this.walk_Left = { start: undefined, end: undefined,
|
||||
reaction: [{name: "walk", chance: "0-50"}, {name: "jumpAsidePunch", chance: "50-60"}, {name: "stand", chance: "60-80"}, {name: "jumpAside", chance: "80-100"}]
|
||||
};
|
||||
this.kick_Right_Up = { start: undefined, end: undefined, once: true, damage: 1, cool_down: 4,
|
||||
reaction: [{name: "block", chance: "0-50"}, {name: "punch", chance: "50-80"}, {name: "stand", chance: "80-100"}]
|
||||
};
|
||||
this.kick_Left_Up = { start: undefined, end: undefined, once: true, damage: 1, cool_down: 4,
|
||||
reaction: [{name: "block", chance: "0-50"}, {name: "punch", chance: "50-80"}, {name: "stand", chance: "80-100"}]
|
||||
};
|
||||
this.jumpAside_Right = {};
|
||||
this.jumpAside_Left = {};
|
||||
this.jumpAsidePunch_Right = {};
|
||||
this.jumpAsidePunch_Left = {};
|
||||
this.walkAway_Right = {};
|
||||
this.walkAway_Left = {};
|
||||
}
|
||||
}
|
66
index.html
Normal file
@ -0,0 +1,66 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>2D Игра</title>
|
||||
</head>
|
||||
<body>
|
||||
<style type="text/css">
|
||||
body{
|
||||
background: black;
|
||||
overflow: hidden;
|
||||
}
|
||||
.top-div {
|
||||
display: flex;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 10px;
|
||||
font-family: "Arial";
|
||||
font-size: 10px;
|
||||
background: black;
|
||||
color: white;
|
||||
}
|
||||
.top-div::after {
|
||||
content: "Загрузка";
|
||||
display: flex;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
animation: loading 1s ease-in-out infinite;
|
||||
font-size: 30px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
@keyframes loading{
|
||||
0% {
|
||||
content: "Загрузка\00a0\00a0\00a0";
|
||||
}
|
||||
35% {
|
||||
content: "Загрузка.\00a0\00a0";
|
||||
}
|
||||
65% {
|
||||
content: "Загрузка..\00a0";
|
||||
}
|
||||
100% {
|
||||
content: "Загрузка...";
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<div class="container">
|
||||
<canvas id="gameCanvas"></canvas>
|
||||
<canvas id="introCanvas"></canvas>
|
||||
<canvas id="textCanvas"></canvas>
|
||||
<div class="top-div"></div>
|
||||
</div>
|
||||
<script src="./chars.js"></script>
|
||||
<script src="./typing.js"></script>
|
||||
<script src="./frame_data.js"></script>
|
||||
<script src="./ui_panel.js"></script>
|
||||
<script src="./player.js"></script>
|
||||
<script src="./enemy.js"></script>
|
||||
<script src="./battle.js"></script>
|
||||
</body>
|
||||
</html>
|
647
player.js
Normal file
@ -0,0 +1,647 @@
|
||||
class Player{
|
||||
constructor(w, h, image, dx, type, name, frameWidth = 224, frameHeight = 214,
|
||||
frameSpeed = 1, size = 1){
|
||||
if(type == "bot"){
|
||||
this.direction = '_Left';
|
||||
}
|
||||
else{
|
||||
this.direction = '_Right';
|
||||
}
|
||||
this.size = size;
|
||||
this.x = w / 10 + dx;
|
||||
this.y = canvas.height - this.frameHeight / 2;
|
||||
this.frameWidth = frameWidth;
|
||||
this.frameHeight = frameHeight;
|
||||
this.currentFrame = 0;
|
||||
this.currentAction = "stand" + this.direction;
|
||||
this.frameSpeed = frameSpeed;
|
||||
this.speed = 30;
|
||||
this.dx = 0;
|
||||
this.dy = 0;
|
||||
this.image = image;
|
||||
this.stopped = false; // блокировка передвижения
|
||||
this.stopCount = 0; // счетчик блокировки передвижения, по достижении нужного значения
|
||||
// персонаж снова сможет передвигаться
|
||||
this.nemesis = null; // противник
|
||||
this.type = type; // тип персонажа: игрок или робот
|
||||
this.name = name;
|
||||
this.idleCount = 0; // счтечик бездействия
|
||||
this.maxIdle = 60;
|
||||
this.min_distance = 70; // минимальное значение дистанции коллизии
|
||||
this.max_distance = 300; // максимальное значение дистанции коллизии
|
||||
this.health = {
|
||||
max: 100,
|
||||
current: 100
|
||||
}
|
||||
this.rage = { //Ярость
|
||||
max: 100,
|
||||
current: 0,
|
||||
}
|
||||
this.stunCount = 0; // оглушение, когда соперник бьет критом после накопления яорсти
|
||||
this.coolDown = 0; // кулдаун на все действия после обычного действия, например, блока
|
||||
this.coolDownArray = []; // массив кулдаунов конкретных ударов
|
||||
}
|
||||
collision(){
|
||||
if(this.type == "bot"){
|
||||
this.potential_nemesis = game.player;
|
||||
}
|
||||
else{
|
||||
this.potential_nemesis = game.characters.enemy;
|
||||
}
|
||||
|
||||
// бот всегда смотрит в сторону игрока
|
||||
if(this.type == "bot" && this.potential_nemesis){
|
||||
if(this.potential_nemesis.x <= this.x){
|
||||
this.direction = "_Left";
|
||||
}
|
||||
else{
|
||||
this.direction = "_Right";
|
||||
}
|
||||
}
|
||||
|
||||
if(this.potential_nemesis){
|
||||
this.collision_distance = Math.abs(this.potential_nemesis.x - this.x);
|
||||
}
|
||||
|
||||
// переходим в остояние боя, если дистанция меньше определенного значения
|
||||
if(this.collision_distance <= this.min_distance){
|
||||
if(!this.potential_nemesis.dy && !this.dy){ // Если мы в прыжке, то коллизия не срабатывает
|
||||
this.nemesis = this.potential_nemesis;
|
||||
|
||||
if(this.stopCount >= 5){
|
||||
this.stopped = false;
|
||||
}
|
||||
else if(this.nemesis.stunCount == 0){
|
||||
if(!this.stopped){
|
||||
this.stopCount = 1;
|
||||
}
|
||||
this.stopped = true;
|
||||
}
|
||||
if(this.stopCount > 10){
|
||||
this.stopCount = 1;
|
||||
}
|
||||
if(this.stopCount > 0){
|
||||
this.stopCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(this.nemesis){ // вышли из коллизии
|
||||
this.nemesis = null;
|
||||
this.stopped = false;
|
||||
this.stopCount = 0;
|
||||
}
|
||||
if(this.collision_distance < this.max_distance){
|
||||
this.idleCount = 0;
|
||||
}
|
||||
if(this.collision_distance < this.max_distance || this.idleCount > this.maxIdle){
|
||||
|
||||
}
|
||||
else{
|
||||
this.stopped = false;
|
||||
this.stopCount = 0;
|
||||
}
|
||||
}
|
||||
update(){
|
||||
if(!game.intro){
|
||||
this.idleCount++;
|
||||
}
|
||||
|
||||
if(this.type == "player"){
|
||||
const action = Object.keys(key_down)[Object.keys(key_down).length - 1];
|
||||
|
||||
if(action){
|
||||
// Вызываем действие, если кнопка нажата и действие еще не выполнено
|
||||
// либо кнопка зажата и мы идем
|
||||
// При этом предыдущее действие либо закончено (т.е. currentFrame == 0),
|
||||
// либо мы стоим, прыгаем или присели (т.е. действия не once и не no_return)
|
||||
if( (key_down[action] != false || action.split("_")[0] == "walk")
|
||||
&& (this.currentFrame == 0
|
||||
|| !frame_data[this.name][this.currentAction].once
|
||||
|| (frame_data[this.name][this.currentAction].no_return
|
||||
&&
|
||||
this.currentFrame >= frame_data[this.name][this.currentAction].end - frame_data[this.name][this.currentAction].start - 1
|
||||
)
|
||||
)
|
||||
){
|
||||
|
||||
if(action.split("_")[0] != "walk"){
|
||||
key_down[action] = false
|
||||
}
|
||||
|
||||
if( !( action.split("_")[0] == "walk" && this.currentAction == "walk" + this.direction ) ){
|
||||
// console.log(this.currentAction, this.currentFrame)
|
||||
this.doAction(action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Если идем, и нажата кнопка, лействие которой не jump и не walk
|
||||
if(
|
||||
key_down["walk" + this.direction]
|
||||
&& this.currentAction.split("_")[0] != "walk"
|
||||
&& this.currentAction.split("_")[0] != "jump"
|
||||
|
||||
||
|
||||
|
||||
this.currentAction == "walk" + this.direction
|
||||
&& !key_down[this.currentAction]
|
||||
|
||||
){
|
||||
this.dx = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(this.stunCount && this.stunCount <= 2){
|
||||
this.stunCount++;
|
||||
const count = 5; // число шагов (чем выше, тем быстрее)
|
||||
// Если противник кританул, нас отталкивает за дистанцию боя,
|
||||
// то есть меняется dx, замедляясь к концу движения
|
||||
if(this.nemesis && this.stunCount > 0 && this.stunCount < count){
|
||||
this.nemesis.stopped = false;
|
||||
this.doAction('stand' + this.direction);
|
||||
// косинус менятеся от 1 (при аргументе 0) до 0 (при аргументе Math.PI/2)
|
||||
// this.stunCount изначальо будет равен 2, поэтому чтобы получить ноль, пишем this.stunCount-2
|
||||
// делим Math.PI / 2 на count и получаем число секторов, которые надо тпройти
|
||||
// 27 — целое число, при умножении на которое при count = 5 получим целое число, ближайшее к 71 (дистанция боя)
|
||||
// 71 = x * ( Math.cos( 0 * Math.PI / 2 / 5) + Math.cos( 1 * Math.PI / 2 / 5) + Math.cos( 2 * Math.PI / 2 / 5) )
|
||||
// x = 71 / 2.7 = 27
|
||||
this.nemesis.dx = 27 * directions[this.nemesis.direction] * -1 * Math.cos( (this.stunCount - 2) * Math.PI / 2 / count)
|
||||
// console.log(this.nemesis.dx, this.stunCount)
|
||||
}
|
||||
|
||||
}
|
||||
else{
|
||||
this.stunCount = 0;
|
||||
}
|
||||
|
||||
if(this.coolDown && this.coolDown <= 2){
|
||||
this.coolDown++;
|
||||
}
|
||||
else{
|
||||
this.coolDown = 0;
|
||||
}
|
||||
|
||||
this.collision();
|
||||
|
||||
const my_action_params = frame_data[this.name][this.currentAction];
|
||||
if(!game.over || game.info_animation_timer){
|
||||
if(this.rage.current > 0){
|
||||
if(!this.nemesis){
|
||||
this.rage.current -= 0.2;
|
||||
}
|
||||
else{
|
||||
this.rage.current -= 0.1;
|
||||
}
|
||||
}
|
||||
else{
|
||||
this.rage.current = 0;
|
||||
}
|
||||
|
||||
if(this.nemesis){
|
||||
const nemesis_action_params = frame_data[this.nemesis.name][this.nemesis.currentAction];
|
||||
if(this.type == "bot"){
|
||||
if(this.nemesis.currentAction.split("_")[0] != "walk"){
|
||||
this.reaction(nemesis_action_params);
|
||||
}
|
||||
// если идем во время боя, то реакция как на действие stand
|
||||
else{
|
||||
this.reaction(frame_data[this.name]["stand" + this.nemesis.direction]);
|
||||
}
|
||||
}
|
||||
this.block(nemesis_action_params, my_action_params);
|
||||
}
|
||||
this.countFrameData(my_action_params);
|
||||
}
|
||||
this.draw();
|
||||
}
|
||||
countFrameData(my_action_params){
|
||||
// game.player.rage.current = 100;
|
||||
// Если анимаци продолжается, то есть номер кадра менбше разнициы end и start
|
||||
var action = frame_data[this.name][this.currentAction];
|
||||
|
||||
if(action && this.currentFrame < frame_data[this.name][this.currentAction].end - frame_data[this.name][this.currentAction].start - 1){
|
||||
if(frame_data[this.name][this.currentAction].speed){
|
||||
this.currentFrame = Math.round(this.currentFrame
|
||||
+ frame_data[this.name][this.currentAction].speed);
|
||||
}
|
||||
else{
|
||||
this.currentFrame = Math.round(this.currentFrame + this.frameSpeed);
|
||||
}
|
||||
// Если прыжок и нет верхнего удара
|
||||
if(this.dy && this.currentAction.split("_")[0] != "kick"
|
||||
&& this.currentAction.split("_")[2] != "Up"){
|
||||
// узнаем номер кадра в прыжке делением текущего значения dy на восьмую часть максимального значения dy.
|
||||
// 8 — число кадров в анимации прыжка
|
||||
this.currentFrame = Math.ceil( this.dy / (Math.PI / 8) );
|
||||
}
|
||||
|
||||
if(!this.stopped && this.x >= 0 && this.x <= canvas.width){
|
||||
this.x += this.dx;
|
||||
if(this.x < 0){
|
||||
this.x = 0;
|
||||
}
|
||||
else if(this.x > canvas.width){
|
||||
this.x = canvas.width;
|
||||
}
|
||||
}
|
||||
|
||||
if(this.type == "player"){
|
||||
// console.log(key_down["walk" + this.direction], "walk" + this.direction, this.currentAction)
|
||||
}
|
||||
}
|
||||
// Если анимация завершилась
|
||||
else{
|
||||
this.complex = false;
|
||||
// Если отжата кнопка,
|
||||
// то меняем действие на stand и обнуляем dx, на случай если персонаж шел
|
||||
// if(this.type == "player"){
|
||||
// console.log(key_down[this.currentAction.split("_")[0]], this.currentAction.split("_")[0], this.currentAction)
|
||||
// }
|
||||
if(this.currentAction.split("_")[0] == "walk"){
|
||||
var current_action = this.currentAction;
|
||||
}
|
||||
else{
|
||||
var current_action = this.currentAction + this.direction;
|
||||
}
|
||||
|
||||
if(!key_down[current_action] || this.type == "bot"){
|
||||
if(this.type == "player"){
|
||||
// console.log("Отжата", current_action, key_down[current_action])
|
||||
}
|
||||
if(this.type != "bot" && !arrow_down || this.type == "bot" && !this.crouch ||
|
||||
this.stunCount > 0){
|
||||
|
||||
if(this.type == "bot"){
|
||||
// console.log(this.currentFrame, this.currentAction, frame_data[this.name][this.currentAction].end - frame_data[this.name][this.currentAction].start - 1)
|
||||
}
|
||||
// Встаем
|
||||
this.doAction('stand' + this.direction);
|
||||
if(this.type != "bot" && this.nemesis && this.nemesis.crouch){
|
||||
this.nemesis.crouch = false;
|
||||
}
|
||||
}
|
||||
// Если не нажата кнопка вниз
|
||||
else{
|
||||
// Продолжаем сидеть
|
||||
this.currentAction = "crouch" + this.direction + "_Down";
|
||||
}
|
||||
this.dx = 0;
|
||||
}
|
||||
// Иначе просто обнуляем currentFrame кадра и анимация начнется снова
|
||||
else{
|
||||
if(!my_action_params.no_return
|
||||
&& this.currentAction.split("_")[0] != "walk"){
|
||||
key_down[this.currentAction] = false;
|
||||
this.doAction('stand' + this.direction);
|
||||
}
|
||||
else if(!my_action_params.once){
|
||||
this.currentFrame = 0;
|
||||
if(!this.stopped && this.x >= 0 && this.x <= canvas.width){
|
||||
this.x += this.dx; // добавляем для плавности перемещение в конце анимации walk
|
||||
if(this.x < 0){
|
||||
this.x = 0;
|
||||
}
|
||||
else if(this.x > canvas.width){
|
||||
this.x = canvas.width;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// условие для прыжка
|
||||
if(this.dy){
|
||||
// примем максимально значение dy за число пи
|
||||
if(this.dy <= Math.PI){
|
||||
// косинус менятеся от 1 (при dy = 0) до 0 (при dy = Math.PI/2) и снова до 1 (при dy = Math.PI)
|
||||
// Поэтому к середине прыжка скорость замедлится до 0 (5 * 0 = 0)
|
||||
this.y -= 50 * Math.cos(this.dy);
|
||||
this.dy += Math.PI / 8;
|
||||
}
|
||||
// прыжок закончился
|
||||
if(this.dy > Math.PI){
|
||||
this.dy = 0;
|
||||
this.dx = 0;
|
||||
// key_down["walk" + this.direction] = false;
|
||||
if(!game.info_animation_timer){
|
||||
this.y = canvas.height - this.frameHeight / 2;
|
||||
}
|
||||
else{
|
||||
this.y = 100;
|
||||
}
|
||||
this.doAction('stand' + this.direction);
|
||||
this.currentFrame = 0;
|
||||
}
|
||||
}
|
||||
// если прыжка нет, то персонаж всегда внизу экрана, даже если изменили размер окна
|
||||
else{
|
||||
if(!game.info_animation_timer){
|
||||
this.y = canvas.height - this.frameHeight / 2;
|
||||
}
|
||||
else{
|
||||
this.y = 100;
|
||||
}
|
||||
}
|
||||
}
|
||||
block(nemesis_action_params, my_action_params){
|
||||
// Проверка на блок и пересчет здоровья
|
||||
const [action_name, action_hor_direct, action_vert_direct] = this.currentAction.split("_");
|
||||
const [nemesis_action_name, nemesis_action_hor_direct, nemesis_action_vert_direct] = this.nemesis.currentAction.split("_");
|
||||
const condition = this.nemesis.currentFrame == Math.round((nemesis_action_params.end - nemesis_action_params.start) / 2);
|
||||
const start = nemesis_action_params.start;
|
||||
const condition2 = "active" in nemesis_action_params
|
||||
&& start + this.nemesis.currentFrame > nemesis_action_params.active.start
|
||||
&& start + this.nemesis.currentFrame < nemesis_action_params.active.end;
|
||||
|
||||
// if(this.type == "player" && nemesis_action_params.active){
|
||||
// console.log(start + this.nemesis.currentFrame , nemesis_action_params.active.start
|
||||
// , nemesis_action_params.active.end, start + this.nemesis.currentFrame > nemesis_action_params.active.start
|
||||
// , start + this.nemesis.currentFrame < nemesis_action_params.active.end)
|
||||
// }
|
||||
|
||||
if("damage" in nemesis_action_params &&
|
||||
(nemesis_action_hor_direct == "Left" && this.nemesis.x > this.x ||
|
||||
nemesis_action_hor_direct == "Right" && this.nemesis.x < this.x)
|
||||
&& (condition || condition2) ){
|
||||
let resist = 0;
|
||||
|
||||
// противодействие урону
|
||||
const start2 = frame_data[this.name][this.currentAction].start;
|
||||
const condition3 = "active" in frame_data[this.name][this.currentAction]
|
||||
&& start2 + this.currentFrame > frame_data[this.name][this.currentAction].active.start
|
||||
&& start2 + this.currentFrame < frame_data[this.name][this.currentAction].active.end;
|
||||
|
||||
// if(this.type == "player"){
|
||||
// console.log()
|
||||
// }
|
||||
let damage = nemesis_action_params.damage * 3;
|
||||
// Чем выше урон от противника, тем выше ярость
|
||||
const rage_delta = 10 * damage;
|
||||
if(condition3 && "resist" in my_action_params){ // если действие содержит resist
|
||||
// проверяем разнонаправленность по горизонтали ("_Left", "_Right")
|
||||
|
||||
if(action_hor_direct != nemesis_action_hor_direct){
|
||||
// проверяем совпадение направления по вертиакали ("Up", "Down", undefined)
|
||||
if(action_vert_direct == nemesis_action_vert_direct){
|
||||
resist = my_action_params.resist;
|
||||
this.nemesis.coolDown = 2;
|
||||
}
|
||||
}
|
||||
else{
|
||||
this.rage.current += rage_delta;
|
||||
}
|
||||
this.stopCount += 25;
|
||||
}
|
||||
else{
|
||||
this.rage.current += rage_delta;
|
||||
}
|
||||
|
||||
if(this.rage.current > this.rage.max){
|
||||
this.rage.current = this.rage.max;
|
||||
}
|
||||
|
||||
if(this.nemesis.rage.current >= this.nemesis.rage.max * 0.9){
|
||||
damage *= 10;
|
||||
this.nemesis.stunCount = 1;
|
||||
if(this.type == "player"){
|
||||
this.nemesis.doAction("punch" + this.nemesis.direction);
|
||||
}
|
||||
this.nemesis.rage.current = 0;
|
||||
}
|
||||
|
||||
this.health.current -= damage - resist;
|
||||
if(this.health.current <= 0){
|
||||
this.health.current = 0;
|
||||
game.over = true;
|
||||
if(this.type == "bot"){
|
||||
player_win++;
|
||||
}
|
||||
else{
|
||||
bot_win++;
|
||||
}
|
||||
round++;
|
||||
game.checkWin();
|
||||
}
|
||||
}
|
||||
}
|
||||
draw(){
|
||||
const key = frame_data[this.name][this.currentAction];
|
||||
if(key){
|
||||
const { start, end } = key;
|
||||
ctx.drawImage(this.image,
|
||||
(start + this.currentFrame) * this.frameWidth, 0,
|
||||
this.frameWidth, this.frameHeight,
|
||||
this.x - this.frameWidth / 2, this.y - this.frameHeight / 2, this.frameWidth * this.size, this.frameHeight * this.size);
|
||||
}
|
||||
}
|
||||
// метод объединяет вызов анимации и метода действия (чтобы не вызывать анимацию в каждом действии отдельно)
|
||||
doAction(action){
|
||||
if(this.type != "bot"){
|
||||
if(frame_data[this.name][action]){
|
||||
if("cool_down" in frame_data[this.name][action]){
|
||||
if(!this.coolDownArray[action]){
|
||||
this.coolDownArray[action] = 0;
|
||||
}
|
||||
if(action == this.currentAction){
|
||||
this.coolDownArray[action]++;
|
||||
}
|
||||
else{
|
||||
this.coolDownArray[action] = 0;
|
||||
}
|
||||
// console.log(this.coolDownArray[action], action, this.currentAction)
|
||||
}
|
||||
}
|
||||
}
|
||||
// frame_data[this.name][action].cool_down - 1 — отсчет от нуля, а ключ объекта от единицы
|
||||
if(this.stunCount > 0 || this.coolDown > 0
|
||||
|| frame_data[this.name][action]
|
||||
&& frame_data[this.name][action].cool_down
|
||||
&& this.coolDownArray[action]
|
||||
&& this.coolDownArray[action] >= frame_data[this.name][action].cool_down - 1 ){
|
||||
|
||||
if(this.coolDownArray[action] >= frame_data[this.name][action].cool_down - 1){
|
||||
this.coolDownArray[action] = 0;
|
||||
this.stunCount = 1;
|
||||
}
|
||||
|
||||
// перезаписываем action
|
||||
action = "stand" + this.direction;
|
||||
}
|
||||
if(!this.dy){ // производим удар, только если мы не в прыжке
|
||||
// Сложные действия, состоящие из нескольких, вернут флаг true.
|
||||
let complicated_action_flag;
|
||||
if(this[action]){
|
||||
complicated_action_flag = this[action](action); // вызываем конкретный метод действия или удара
|
||||
}
|
||||
else{
|
||||
console.log("Нет такого действия " + action + " в объекте frame_data[this.name]")
|
||||
}
|
||||
|
||||
// Без этого флага будет пытаться названчить в this.currentAction несуществующее действие
|
||||
if(frame_data[this.name][action] && !complicated_action_flag){
|
||||
this.currentAction = action; // это в том числе идентификатор для анимации
|
||||
}
|
||||
}
|
||||
// если в прыжке, то выполняются только верхние удары (все верхние удары называются kick)
|
||||
else{
|
||||
if(action.split("_")[0] == "kick" && action.split("_")[2] == "Up"){
|
||||
this.currentAction = action;
|
||||
}
|
||||
}
|
||||
this.currentFrame = 0;
|
||||
}
|
||||
jumpAside_Right(){
|
||||
this.doAction("walk_Right");
|
||||
this.doAction("jump_Right");
|
||||
return true;
|
||||
}
|
||||
jumpAside_Left(){
|
||||
this.doAction("walk_Left");
|
||||
this.doAction("jump_Left");
|
||||
return true;
|
||||
}
|
||||
jumpAsidePunch_Right(){
|
||||
this.doAction("walk_Right");
|
||||
this.doAction("jump_Right");
|
||||
let context = this;
|
||||
setTimeout(function(){
|
||||
context.complex = true;
|
||||
context.direction = "_Right"
|
||||
context.doAction("kick_Right_Up")
|
||||
console.log(context.currentAction, context.direction)
|
||||
} , 100);
|
||||
return true;
|
||||
}
|
||||
jumpAsidePunch_Left(){
|
||||
this.doAction("walk_Left");
|
||||
this.doAction("jump_Left");
|
||||
let context = this;
|
||||
setTimeout(function(){
|
||||
context.complex = true;
|
||||
context.direction = "_Left"
|
||||
context.doAction("kick_Left_Up")
|
||||
} , 100);
|
||||
return true;
|
||||
}
|
||||
walkAway_Left(){
|
||||
if(!this.crouch){
|
||||
this.doAction("walk_Right");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
walkAway_Right(){
|
||||
if(!this.crouch){
|
||||
this.doAction("walk_Left");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
walk_Left(){
|
||||
if(!this.stopped){
|
||||
this.dx = -this.speed;
|
||||
}
|
||||
this.direction = '_Left';
|
||||
}
|
||||
walk_Right(){
|
||||
if(!this.stopped){
|
||||
this.dx = this.speed;
|
||||
}
|
||||
this.direction = '_Right';
|
||||
}
|
||||
punch_Right(){
|
||||
|
||||
}
|
||||
punch_Left(){
|
||||
|
||||
}
|
||||
punch_Right_Down(){
|
||||
|
||||
}
|
||||
punch_Left_Down(){
|
||||
|
||||
}
|
||||
block_Right(){
|
||||
|
||||
}
|
||||
block_Left(){
|
||||
|
||||
}
|
||||
block_Right_Up(){
|
||||
|
||||
}
|
||||
block_Left_Up(){
|
||||
|
||||
}
|
||||
block_Right_Down(){
|
||||
|
||||
}
|
||||
block_Left_Down(action){
|
||||
// if(this.currentAction != "crouch_Left"){
|
||||
// this.doAction("crouch_Left");
|
||||
// // let context = this;
|
||||
// // setTimeout(function(){
|
||||
// // // context.complex = true;
|
||||
// // context.doAction("punch_Left")
|
||||
// // } , 100);
|
||||
// }
|
||||
// // else{
|
||||
// // this.currentAction = action;
|
||||
// // }
|
||||
// return true;
|
||||
}
|
||||
jump_Right(){
|
||||
this.dy = 0.1;
|
||||
}
|
||||
jump_Left(){
|
||||
this.dy = 0.1;
|
||||
}
|
||||
crouch_Right_Down(){
|
||||
if(this.type == "bot"){
|
||||
this.crouch = true;
|
||||
}
|
||||
}
|
||||
crouch_Left_Down(){
|
||||
if(this.type == "bot"){
|
||||
this.crouch = true;
|
||||
}
|
||||
}
|
||||
crouch_Right_Up(){
|
||||
if(this.type == "bot"){
|
||||
this.crouch = false;
|
||||
}
|
||||
}
|
||||
crouch_Left_Up(){
|
||||
if(this.type == "bot"){
|
||||
this.crouch = false;
|
||||
}
|
||||
}
|
||||
kick_Right_Up(){
|
||||
|
||||
}
|
||||
kick_Left_Up(){
|
||||
|
||||
}
|
||||
stand_Left(action){
|
||||
if(this.currentAction == "crouch_Left_Down"){
|
||||
this.currentAction = "crouch_Left_Up";
|
||||
}
|
||||
else{
|
||||
this.currentAction = action;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
stand_Right(action){
|
||||
if(this.currentAction == "crouch_Right_Down"){
|
||||
this.currentAction = "crouch_Right_Up";
|
||||
}
|
||||
else{
|
||||
this.currentAction = action;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
test_Left(){
|
||||
console.log("Left_________________________");
|
||||
}
|
||||
test_Right(){
|
||||
console.log("Right_________________________");
|
||||
}
|
||||
}
|
39
typing.js
Normal file
@ -0,0 +1,39 @@
|
||||
|
||||
|
||||
function type(ctx_name, mystring, x0, y0, size, align, input_width, input_height){
|
||||
var newline = 0;
|
||||
var outdent = 0;
|
||||
texgo = letters["a"];
|
||||
|
||||
if(align == "center"){
|
||||
var cell_size = Math.floor(size / texgo.length);
|
||||
x0 = x0 + input_width / 2 - mystring.length * ((texgo[0].length + 1) * cell_size ) / 2;
|
||||
y0 = y0 + input_height / 2- ((texgo.length + 1) * cell_size ) / 2;
|
||||
}
|
||||
else{
|
||||
var cell_size = size;
|
||||
}
|
||||
|
||||
// ctx_name.clearRect(x0, y0, x0 + mystring.length * ((texgo[0].length + 1) * cell_size ), y0 + texgo.length * cell_size);
|
||||
for (var i = 0; i < mystring.length; i++){
|
||||
|
||||
if (mystring[i] == "&"){
|
||||
newline+= 8 + 4;
|
||||
outdent = 0;
|
||||
}
|
||||
else{
|
||||
texgo = letters[mystring[i]];
|
||||
if(texgo){
|
||||
for (var x = 0; x < texgo.length; x++){
|
||||
for (var y = 0; y <= texgo[0].length; y++){
|
||||
if (texgo[x][y] == 1){
|
||||
ctx_name.fillStyle = "white";
|
||||
ctx_name.fillRect(x0 + (y + (texgo[0].length + 1) *outdent)*cell_size, y0 + (newline + x)*cell_size, cell_size, cell_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
outdent++;
|
||||
}
|
||||
}
|
||||
}
|
168
ui_panel.js
Normal file
@ -0,0 +1,168 @@
|
||||
|
||||
class UI{
|
||||
drawUserInfo(x, y, size, avatar, persone, name, n) {
|
||||
const ratio = avatar.width / avatar.height;
|
||||
const avatar_w = size / 2.5;
|
||||
const avatar_h = avatar_w * ratio;
|
||||
|
||||
var j = 10, j2 = 5, outdent_x1, outdent_x2;
|
||||
if(n > 0){
|
||||
outdent_x1 = 0 - j;
|
||||
outdent_x2 = avatar_w - j;
|
||||
}
|
||||
else{
|
||||
outdent_x1 = -(avatar_w - 20 - j2);
|
||||
outdent_x2 = avatar_w - 20 + j2;
|
||||
}
|
||||
|
||||
ctx.fillStyle = "rgba(28, 128, 128, 0.7)";
|
||||
ctx.fillRect(x + outdent_x1, y - 40, size + outdent_x2, y + 17 + 10)
|
||||
|
||||
ctx.fillStyle = "#FFFFFF";
|
||||
ctx.font = "25px Arial ";
|
||||
ctx.textAlign = "center";
|
||||
ctx.fillText(name, x + size / 2, y - 10);
|
||||
|
||||
ctx.drawImage(avatar, x + n, 10, avatar_h, avatar_w);
|
||||
|
||||
var rage;
|
||||
if(persone.rage.current >= persone.rage.max * 0.9){
|
||||
ctx.drawImage(images[persone.type + "_avatar_rage"], x + n, 10, avatar_h, avatar_w);
|
||||
rage = size;
|
||||
}
|
||||
else{
|
||||
rage = size / persone.rage.max * persone.rage.current;
|
||||
}
|
||||
|
||||
ctx.fillStyle = "FireBrick";
|
||||
ctx.fillRect(x, y + 5, size / persone.health.max * persone.health.current, 10);
|
||||
ctx.fillStyle = "DarkOrange";
|
||||
ctx.fillRect(x, y + 17, rage, 10);
|
||||
|
||||
// if(persone.stopped || persone.stunCount > 0){
|
||||
// ctx.drawImage(images.lock, x + n + outdent_x1 + 55, 10, 20, 20);
|
||||
// }
|
||||
// if(persone.nemesis && persone.nemesis.coolDown > 0 || persone.block_ind){
|
||||
// if(!persone.block_ind){
|
||||
// setTimeout(function(){
|
||||
// persone.block_ind = false;
|
||||
// }, 200, persone)
|
||||
// }
|
||||
// persone.block_ind = true;
|
||||
// ctx.drawImage(images.block, x + n + outdent_x1 + 55, y + 17 + 10, 20, 20);
|
||||
// }
|
||||
|
||||
game.time_bar.caption = "Time left: " + String( game.round_time - game.seconds );
|
||||
|
||||
}
|
||||
drawStartScreen(pers_image, bot_image, text_image, n, delay){
|
||||
this.clearAll();
|
||||
intro_ctx.beginPath();
|
||||
intro_ctx.moveTo(canvas.width - n, canvas.height);
|
||||
intro_ctx.lineTo(0 - n, canvas.height);
|
||||
intro_ctx.lineTo(canvas.width - n, 0);
|
||||
intro_ctx.closePath();
|
||||
intro_ctx.fill();
|
||||
intro_ctx.globalCompositeOperation="source-out";
|
||||
this.drawStartImage(intro_ctx, pers_image, -n - 1);
|
||||
intro_ctx.globalCompositeOperation="source-over";
|
||||
this.drawStartImage(intro_ctx, bot_image, n + 1);
|
||||
}
|
||||
drawStartImage(ctx, image, n){
|
||||
if(n > 0){
|
||||
var x0 = canvas.width - image.width * 1.5;
|
||||
}
|
||||
else{
|
||||
var x0 = 0;
|
||||
}
|
||||
ctx.drawImage(image,
|
||||
x0 + n, 0,
|
||||
image.width * 1.5, image.height * 1.5);
|
||||
}
|
||||
drawGameCaption(ctx, image, mask, n){
|
||||
const scale = 1.5;
|
||||
|
||||
ctx.drawImage(image,
|
||||
canvas.width / 2 - image.width / 2 / scale,
|
||||
canvas.height / 2 - image.height / 2 / scale,
|
||||
image.width / scale, image.height / scale);
|
||||
|
||||
if(mask){
|
||||
ctx.globalCompositeOperation="source-out";
|
||||
ctx.fillStyle = "white";
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height)
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(n * 2, canvas.height / 2 - 50);
|
||||
ctx.lineTo(n * 2 + 20, canvas.height / 2 + 50);
|
||||
ctx.lineTo(n * 2 + 30, canvas.height / 2 + 50);
|
||||
ctx.lineTo(n * 2 + 20, canvas.height / 2 - 50);
|
||||
ctx.moveTo(n * 2, canvas.height / 2 - 50);
|
||||
ctx.closePath();
|
||||
ctx.fill();
|
||||
}
|
||||
else{
|
||||
ctx.globalCompositeOperation="source-over";
|
||||
}
|
||||
}
|
||||
clearAll(){
|
||||
intro_ctx.clearRect(0,0,canvas.width,canvas.height);
|
||||
text_ctx.clearRect(0,0,canvas.width,canvas.height);
|
||||
}
|
||||
drawTimeBar(ctx, image, mask, n, scale){
|
||||
ctx.drawImage(image,
|
||||
canvas.width / 2 - image.width / 2 * scale,
|
||||
canvas.height / 2 - image.height / 2 * scale,
|
||||
image.width * scale, image.height * scale);
|
||||
|
||||
if(mask){
|
||||
ctx.globalCompositeOperation="source-out";
|
||||
ctx.fillStyle = "white";
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height)
|
||||
ctx.fillStyle = "red";
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height)
|
||||
}
|
||||
else{
|
||||
ctx.globalCompositeOperation="source-over";
|
||||
}
|
||||
}
|
||||
}
|
||||
class Square{
|
||||
constructor(ctx_name, x, y, width, height, background, value) {
|
||||
this.ctx = ctx_name;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.background = background;
|
||||
this.value = value;
|
||||
this.v;
|
||||
this.cap;
|
||||
}
|
||||
set value(value){
|
||||
this.v = value;
|
||||
}
|
||||
get value(){
|
||||
return this.v;
|
||||
}
|
||||
set background(background){
|
||||
if (background == "" || background == undefined){
|
||||
// ctx.clearRect(this.x * this.width, this.y * this.height, this.width, this.height);
|
||||
}
|
||||
else{
|
||||
ctx.fillStyle = background;
|
||||
ctx.beginPath();
|
||||
ctx.roundRect(this.x * this.width, this.y * this.height, this.width, this.height, [10]);
|
||||
ctx.fill();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
class Button extends Square {
|
||||
set caption(caption){
|
||||
this.cap = caption;
|
||||
type(ctx, caption, this.x * this.width, this.y * this.height, this.height / 2, "center", this.width, this.height);
|
||||
}
|
||||
get caption(){
|
||||
return this.cap;
|
||||
}
|
||||
}
|