Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions custom_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,47 @@ async def comfy_pets_update_inventory(request):
print("Error:", e)
return web.json_response({ "error": str(e) }, status=400)


@server.PromptServer.instance.routes.get("/comfy-pets/pets")
async def comfy_pets_get_pet(request):
try:
data = persistence.get_current_pet()
return web.json_response({
"pet": data
}, content_type='application/json')
except Exception as e:
print("Error:", e)
return web.json_response({ "error": e }, status=400)

@server.PromptServer.instance.routes.post("/comfy-pets/pets/age")
async def comfy_pets_pets_age(request):
try:
data = await request.json()
age = data.get("age")

persistence.update_pet_age(age)

return web.json_response({
"message": "Pet age updated successfully"
}, content_type='application/json')

except Exception as e:
print("Error:", e)
return web.json_response({ "error": str(e) }, status=400)

@server.PromptServer.instance.routes.post("/comfy-pets/pets/food-consumed")
async def comfy_pets_pets_age(request):
try:
data = await request.json()
amount = data.get("amount")

persistence.update_pet_food_consumed(amount)

return web.json_response({
"message": "Pet consumed updated successfully"
}, content_type='application/json')

except Exception as e:
print("Error:", e)
return web.json_response({ "error": str(e) }, status=400)

48 changes: 48 additions & 0 deletions js/apiClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,54 @@ export const setUserNewInventory = async (inventory) => {
}
}

export const setPetFoodConsumed = async (amount) => {
try {
const url = '/comfy-pets/pets/food-consumed'
const data = {
amount,
}
const requestOptions = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data), // Convert the data to JSON format
}
await fetch(url, requestOptions).then((x) => x.json())
} catch (e) {
throw new Error('Something went wrong')
}
}

export const setPetAge = async (age) => {
try {
const url = '/comfy-pets/pets/age'
const data = {
age,
}
const requestOptions = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data), // Convert the data to JSON format
}
await fetch(url, requestOptions).then((x) => x.json())
} catch (e) {
throw new Error('Something went wrong')
}
}

export const getCurrentPet = async () => {
const url = '/comfy-pets/pets'
const { pet } = await fetchWithCache(url)
let parsedUserData = {
...pet,
['age']: parseInt(pet.age),
}
return parsedUserData
}

export async function ping() {
const user = await getCurrentUser()
const userId = user?.user_id
Expand Down
1 change: 1 addition & 0 deletions js/comfy/comfy.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ export class Button {
this.fontSize = '16'
this.fontFamily = 'Arial'
this.fontWeight = 'regular'
this.visible = false
}

inBounds(mouseX, mouseY) {
Expand Down
5 changes: 5 additions & 0 deletions js/game/buttons.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,14 @@ import { darkenHexColor } from '../utils.js'
export class BaseComfyPetsButton extends Button {
constructor(text, fillColor, textColor) {
super(text, fillColor, textColor)

this.visible = true
}

render(ctx) {
if (!this.visible) {
return
}
// Darken by 10%
const buttonFillDark = darkenHexColor(this.backgroundColor, 10)

Expand Down
128 changes: 105 additions & 23 deletions js/game/pet.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
//import { GIF } from "../libs/gif.js";
import { GameObject } from './core.js'
import { getCurrentPet, setPetAge } from '../apiClient.js'

const BABY_CORGI =
'https://comfyui-output.nyc3.cdn.digitaloceanspaces.com/babycorgi-sprite-128x128.png'
const TEEN_CORGI =
'https://comfyui-output.nyc3.cdn.digitaloceanspaces.com/teencorgi-sprite-128x128.png'
const ADULT_CORGI =
'https://comfyui-output.nyc3.cdn.digitaloceanspaces.com/corgi-sprite-128x128.png'

// Our sprite sheet is on a grid of 64pxs
// Each row is 64px tall, and each frame is 64px wide
Expand Down Expand Up @@ -47,9 +55,10 @@ export class Pet extends GameObject {
super(x, y, height, width)
// Pet state
this.x = x
this.currentDirection = 'right'

this.height = height
this.width = width
this.currentDirection = 'right'

this.emote = false
this.talk = false
Expand All @@ -69,16 +78,29 @@ export class Pet extends GameObject {
// Assets
this.petImage = new Image()
this.petImage.src =
'https://comfyui-output.nyc3.cdn.digitaloceanspaces.com/corgi-sprite-128x128.png'
'https://comfyui-output.nyc3.cdn.digitaloceanspaces.com/babycorgi-sprite-128x128.png'

this.textBubble = new Image()
this.textBubble.src =
'https://comfyui-output.nyc3.cdn.digitaloceanspaces.com/text-bubble.png'

/**
* Creates render sprite functions
* - e.g. renderWalk, renderSniff_walk, renderIdle1
*/
this.age = 0
this._initializePet()
}

async _initializePet() {
const petData = await getCurrentPet()
console.log(petData)
for (const key in petData) {
this[key] = petData[key]
}
}

/**
* Creates a list of animations from a spritesheet
* - e.g. renderWalk, renderSniff_walk, renderIdle1
*/
createSpriteAnimations(image, scaleDownBy) {
Object.keys(SPRITE_SHEET).forEach((animName) => {
// transform name to title case
// FUNC1 -> Func1
Expand All @@ -89,17 +111,30 @@ export class Pet extends GameObject {
const spriteFrames = SPRITE_SHEET[animName].frames
const spriteFramesY = SPRITE_SHEET[animName].row
this[funcName] = (ctx, renderCount, slowFpsBy = 10) => {
this.renderSprite(
this.renderSpriteAnimation(
ctx,
renderCount,
spriteFrames - 1,
spriteFramesY,
slowFpsBy,
image,
{
renderCount,
spriteFrames: spriteFrames - 1,
spriteFramesY,
slowFpsBy,
},
{
scaleDownBy,
},
)
}
})
}

grow() {
if (this.age < 2) {
this.age++
setPetAge(this.age)
}
}

_chooseRandomDirection() {
const directions = ['left', 'right', 'idle1', 'idle2']

Expand Down Expand Up @@ -242,6 +277,8 @@ export class Pet extends GameObject {

// see if objects interact
if (this.isTouching(nearestFood)) {
this.grow()

// Eat food
nearestFood.delete()
this.setEmote()
Expand All @@ -251,23 +288,28 @@ export class Pet extends GameObject {
}
}

renderSprite(
ctx,
renderCount,
spriteFrames,
spriteFramesY,
slowFpsBy = 10, // Slows down fps by n amount
) {
renderSpriteAnimation(ctx, spriteSheet, frameSettings, options) {
const {
renderCount,
spriteFrames,
spriteFramesY,
slowFpsBy: _slowFpsBy, // Slows down fps by n amount
} = frameSettings

let slowFpsBy = _slowFpsBy || 10

const { scaleDownBy } = options

const _spriteFramesY = SPRITE_SIZE * spriteFramesY
const spriteRenderSize = SPRITE_SIZE // This is the final size users see the sprite as
const spriteRenderSize = SPRITE_SIZE / scaleDownBy // This is the final size users see the sprite as
ctx.imageSmoothingEnabled = true
ctx.imageSmoothingQuality = 'high'

// There is 5 frames in the sprite sheet for walking
// so instead of doing this.renderCount % 4 (0 - 5 frames),
// we do 0 - 50 frames and scale down for a lower image fps.
var _frame = renderCount % (spriteFrames * slowFpsBy)
var frame = Math.round(_frame / slowFpsBy)
const _frame = renderCount % (spriteFrames * slowFpsBy)
const frame = Math.round(_frame / slowFpsBy)

const currentRenderFrame = SPRITE_SIZE * frame

Expand All @@ -279,7 +321,7 @@ export class Pet extends GameObject {
ctx.save()
ctx.scale(-1, 1)
ctx.drawImage(
this.petImage,
spriteSheet,
currentRenderFrame,
_spriteFramesY,
SPRITE_SIZE,
Expand All @@ -292,7 +334,7 @@ export class Pet extends GameObject {
ctx.restore()
} else {
ctx.drawImage(
this.petImage,
spriteSheet,
currentRenderFrame,
_spriteFramesY,
SPRITE_SIZE,
Expand Down Expand Up @@ -352,4 +394,44 @@ export class Pet extends GameObject {
ctx.fillText(this.talkText, textX, textY)
}
}

render(ctx, renderCount) {
switch (this.age) {
case 0:
this.petImage.src = BABY_CORGI
this.scaleDownBy = 1.5

break
case 1:
this.petImage.src = TEEN_CORGI
this.scaleDownBy = 1.2

break
case 2:
this.petImage.src = ADULT_CORGI
this.scaleDownBy = 1

break
}

//height = this.height / this.scaleDownBy
//width = this.width / this.scaleDownBy
this.createSpriteAnimations(this.petImage, this.scaleDownBy)

// render emote
if (this.emote) {
ctx.fillStyle = 'blue'
ctx.font = '10px Arial'
ctx.fillText('❤️', this.x + this.width, this.y)
}

// render emote
if (this.talk) {
this.renderTextBubble(ctx)
}

// move the pet
this._showHitBox(ctx)
this.move(ctx, renderCount)
}
}
Loading