shopper.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. import * as THREE from 'three'
  2. import gsap from 'gsap'
  3. import { loadGltf } from './library/loadgltf.js'
  4. import potionIconVertex from './shaders/potionicon/vertex.glsl'
  5. import potionIconFragment from './shaders/potionicon/fragment.glsl'
  6. export default class Shopper {
  7. constructor(game, meshPath, potionInfo, scale, position, rotation, updateFunction) {
  8. this.game = game
  9. this.meshPath = meshPath
  10. this.desiredPotion = potionInfo
  11. this.scale = scale
  12. this.position = position
  13. this.rotation = rotation
  14. this.updateFunction = updateFunction
  15. this.rejectCount = 0
  16. this.rejectionColors = [
  17. new THREE.Color("yellow"),
  18. new THREE.Color("orange"),
  19. new THREE.Color("crimson")
  20. ]
  21. }
  22. async init() {
  23. const reaperMesh = await loadGltf(this.game, this.meshPath)
  24. reaperMesh.scale.copy(this.scale)
  25. this.object3d = new THREE.Group()
  26. this.object3d.add(reaperMesh)
  27. this.object3d.position.set(-15, 0.1, 10)
  28. this.object3d.rotateOnAxis(THREE.Object3D.DEFAULT_UP, this.rotation)
  29. this.game.scene.add(this.object3d)
  30. const defaultPlane = new THREE.PlaneGeometry(1, 1)
  31. const speechBubbleTexture = this.game.textureLoader.load('./textures/speechbubble.png')
  32. const textBubbleMaterial = new THREE.MeshBasicMaterial({
  33. map: speechBubbleTexture,
  34. transparent: true,
  35. side: THREE.DoubleSide,
  36. })
  37. const potionIconTexture = this.game.textureLoader.load(this.desiredPotion.image)
  38. const potionIconUniforms = {
  39. uPotionIcon: { value: potionIconTexture }
  40. }
  41. const potionIcon = new THREE.Mesh(defaultPlane.clone(), new THREE.ShaderMaterial({
  42. uniforms: potionIconUniforms,
  43. vertexShader: potionIconVertex,
  44. fragmentShader: potionIconFragment,
  45. transparent: true,
  46. }))
  47. potionIcon.position.y = 0.085
  48. potionIcon.position.z = 0.05
  49. potionIcon.scale.set(0.5, 0.5, 0.5)
  50. this.requestBillboard = new THREE.Group()
  51. this.billboardSprite = new THREE.Mesh(defaultPlane.clone(), textBubbleMaterial)
  52. this.requestBillboard.add(this.billboardSprite)
  53. this.requestBillboard.add(potionIcon)
  54. this.requestBillboard.position.x = 0
  55. this.requestBillboard.position.y = 2.5
  56. this.requestBillboard.position.z = 0
  57. this.requestBillboard.visible = false
  58. this.object3d.add(this.requestBillboard)
  59. gsap.to(this.object3d.position, {duration: 2, x: this.position.x, y: this.position.y, z: this.position.z})
  60. }
  61. update(elapsedTime) {
  62. this.updateFunction(elapsedTime)
  63. }
  64. showDesire() {
  65. if (this.object3d.wantIsAnimating) {
  66. return
  67. }
  68. this.object3d.wantIsAnimating = true
  69. this.object3d.wantIsAnimating = true
  70. this.requestBillboard.lookAt(this.game.camera.position)
  71. this.requestBillboard.visible = true
  72. this.requestBillboard.position.set(0, 0.5, 0)
  73. this.requestBillboard.scale.set(0, 0, 0)
  74. gsap.to(this.requestBillboard.position, {
  75. duration: 2, y: 2.5, ease: "elastic", onUpdate: () => {
  76. this.requestBillboard.lookAt(this.game.camera.position)
  77. }
  78. })
  79. gsap.to(this.requestBillboard.scale, {
  80. duration: 2, x: 1, y: 1, z: 1, ease: "elastic", onComplete: () => {
  81. this.object3d.wantIsAnimating = false
  82. }
  83. })
  84. }
  85. hideDesire() {
  86. this.object3d.wantIsAnimating = true
  87. gsap.to(this.requestBillboard.position, { duration: 2, y: 0.5, ease: "back" })
  88. gsap.to(this.requestBillboard.scale, {
  89. duration: 2, x: 0, y: 0, z: 0, ease: "back", onComplete: () => {
  90. this.requestBillboard.visible = false
  91. this.object3d.wantIsAnimating = false
  92. }
  93. })
  94. }
  95. acceptPotion() {
  96. //give money
  97. //show happy billboard
  98. }
  99. rejectPotion(rejectAmount = 1) {
  100. this.rejectCount += rejectAmount
  101. this.billboardSprite.material.color = this.rejectionColors[Math.min(2, this.rejectCount - 1)]
  102. }
  103. showSad() {
  104. //show sad billboard
  105. console.log("not what I wanted")
  106. }
  107. isMatchingPotion(possiblePotionInfo) {
  108. return this.desiredPotion.name == possiblePotionInfo.name
  109. }
  110. }