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);

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