Skip to main content

海滩动物游戏

import Konva from 'konva';

// 创建舞台
const stage = new Konva.Stage({
container: 'container',
width: 578,
height: 530,
});

const background = new Konva.Layer();
const animalLayer = new Konva.Layer();
const animalShapes = [];
let score = 0;

// 创建并加载背景图像
const backgroundImage = new Image();
backgroundImage.onload = function() {
const backgroundKonvaImage = new Konva.Image({
image: backgroundImage,
x: 0,
y: 0,
width: stage.width(),
height: stage.height(),
});
background.add(backgroundKonvaImage);
backgroundKonvaImage.moveToBottom();
};
backgroundImage.src = 'https://konvajs.org/assets/beach.png';

// 图像位置
const animals = {
snake: {
x: 10,
y: 70,
},
giraffe: {
x: 90,
y: 70,
},
monkey: {
x: 275,
y: 70,
},
lion: {
x: 400,
y: 70,
},
};

const outlines = {
snake_black: {
x: 275,
y: 350,
},
giraffe_black: {
x: 390,
y: 250,
},
monkey_black: {
x: 300,
y: 420,
},
lion_black: {
x: 100,
y: 390,
},
};

function isNearOutline(animal, outline) {
const a = animal;
const o = outline;
const ax = a.x();
const ay = a.y();

if (ax > o.x - 20 && ax < o.x + 20 && ay > o.y - 20 && ay < o.y + 20) {
return true;
} else {
return false;
}
}

// 创建消息文本
const messageText = new Konva.Text({
text: '啊哈!把动物放在海滩上!',
x: stage.width() / 2,
y: 40,
fontSize: 20,
fontFamily: 'Calibri',
fill: 'white',
align: 'center',
// 为了居中对齐,我们需要设置偏移
offsetX: 200,
});
background.add(messageText);

function updateMessage(text) {
messageText.text(text);
}

function loadImages(sources, callback) {
const assetDir = 'https://konvajs.org/assets/';
const images = {};
let loadedImages = 0;
let numImages = 0;

for (const src in sources) {
numImages++;
}

for (const src in sources) {
images[src] = new Image();
images[src].onload = function () {
if (++loadedImages >= numImages) {
callback(images);
}
};
images[src].src = assetDir + sources[src];
}
}

function initStage(images) {
// 创建可拖拽的动物
for (const key in animals) {
// 匿名函数以引入作用域
(function () {
const privKey = key;
const anim = animals[key];

const animal = new Konva.Image({
image: images[key],
x: anim.x,
y: anim.y,
draggable: true,
});

animal.on('dragstart', function () {
this.moveToTop();
});

/*
* 检查动物是否在正确的位置并
* 如果是,将其固定位置
*/
animal.on('dragend', function () {
const outline = outlines[privKey + '_black'];
if (!animal.inRightPlace && isNearOutline(animal, outline)) {
animal.position({
x: outline.x,
y: outline.y,
});
animal.inRightPlace = true;

if (++score >= 4) {
const text = '你赢了!享受你的战利品!';
updateMessage(text);
}

// 禁用拖放
setTimeout(function () {
animal.draggable(false);
}, 50);
}
});

// 鼠标悬停时动物发光
animal.on('mouseover', function () {
animal.image(images[privKey + '_glow']);
document.body.style.cursor = 'pointer';
});

// 鼠标移出时返回原始状态
animal.on('mouseout', function () {
animal.image(images[privKey]);
document.body.style.cursor = 'default';
});

animal.on('dragmove', function () {
document.body.style.cursor = 'pointer';
});

animalLayer.add(animal);
animalShapes.push(animal);
})();
}

// 创建动物轮廓
for (const key in outlines) {
// 匿名函数以引入作用域
(function () {
const imageObj = images[key];
const out = outlines[key];

const outline = new Konva.Image({
image: imageObj,
x: out.x,
y: out.y,
});

animalLayer.add(outline);
})();
}

stage.add(background);
stage.add(animalLayer);

updateMessage(
'啊哈!把动物放在海滩上!'
);
}

const sources = {
beach: 'beach.png',
snake: 'snake.png',
snake_glow: 'snake-glow.png',
snake_black: 'snake-black.png',
lion: 'lion.png',
lion_glow: 'lion-glow.png',
lion_black: 'lion-black.png',
monkey: 'monkey.png',
monkey_glow: 'monkey-glow.png',
monkey_black: 'monkey-black.png',
giraffe: 'giraffe.png',
giraffe_glow: 'giraffe-glow.png',
giraffe_black: 'giraffe-black.png',
};

// 演示警告:你将需要本地图像文件以使此演示正常工作
loadImages(sources, initStage);

说明: 拖动并放动物到海滩上的轮廓上。当所有动物都正确放置时,你赢了!