123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336 |
- import { Camera } from "../../libraries/Camera.js";
- import { Point } from "../../libraries/spatial/Point.js";
- import { SpritesheetAtlas } from "../../libraries/SpritesheetAtlas.js";
- import { TweenManager, Tween, Easing } from "../../libraries/Tween.js";
- import { Button } from "../../libraries/components/Button.js"
- import { AsyncDataWriter } from "../../libraries/AsyncDataWriter.js";
- import { AsyncDataReader } from "../../libraries/AsyncDataReader.js";
- export class CharacterCreationState {
- constructor(view) {
- this.stateMachine = view.stateMachine
- this.canvasBounds = null
- this.camera = new Camera()
- this.camera.scale = new Point(2, 2)
- this.tweenManager = new TweenManager()
- this.characterAtlas = view.characterAtlas
- this.registeredEvents = {}
- this.bodyType = 0;
- this.allBodies = [
- [0,0], [1,0],
- [0,1], [1,1],
- [0,2], [1,2],
- [0,3], [1,3],
- ]
- this.top = 0;
- this.allTops = [
- [6,0], [7,0], [8,0], [9,0], [10,0], [11,0], [12,0], [13,0], [14,0], [15,0], [16,0], [17,0],
- [6,1], [7,1], [8,1], [9,1], [10,1], [11,1], [12,1], [13,1], [14,1], [15,0], [16,0], [17,0],
- [6,2], [7,2], [8,2], [9,2], [10,2], [11,2], [12,2], [13,2], [14,2], [15,2], [16,2], [17,2],
- [6,3], [7,3], [8,3], [9,3], [10,3], [11,3], [12,3], [13,3], [14,3], [15,3], [16,3], [17,3],
- [6,4], [7,4], [8,4], [9,4], [10,4], [11,4], [12,4], [13,4], [14,4], [15,4], [16,4], [17,4],
- [6,5], [7,5], [8,5], [9,5], [10,5], [11,5], [12,5], [13,5], [14,5], [15,5], [16,5], [17,5],
- [6,6], [7,6], [8,6], [9,6], [10,6], [11,6], [12,6], [13,6], [14,6], [15,6], [16,6], [17,6],
- [6,7], [7,7], [8,7], [9,7], [10,7], [11,7], [12,7], [13,7], [14,7], [15,7], [16,7], [17,7],
- [6,8], [7,8], [8,8], [9,8], [10,8], [11,8], [12,8], [13,8], [14,8], [15,8], [16,8], [17,8],
- [6,9], [7,9], [8,9], [9,9], [10,9], [11,9], [12,9], [13,9], [14,9], [15,9], [16,9], [17,9],
- ]
- this.bottom = 0;
- this.allBottoms = [
- [3,0], [4,0],
- [3,1], [4,1],
- [3,2], [4,2],
- [3,3], [4,3],
- [3,4], [4,4],
- [3,5], [4,5],
- [3,6], [4,6],
- [3,7], [4,7],
- [3,8], [4,8],
- [3,9], [4,9],
- ]
- this.hair = 0;
- this.allHairs = [
- [19,0], [20,0], [21,0], [22,0], [23,0], [24,0], [25,0], [26,0],
- [19,1], [20,1], [21,1], [22,1], [23,1], [24,1], [25,1], [26,1],
- [19,2], [20,2], [21,2], [22,2], [23,2], [24,2], [25,2], [26,2],
- [19,3], [20,3], [21,3], [22,3], [23,3], [24,3], [25,3], [26,3],
- [19,4], [20,4], [21,4], [22,4], [23,4], [24,4], [25,4], [26,4],
- [19,5], [20,5], [21,5], [22,5], [23,5], [24,5], [25,5], [26,5],
- [19,6], [20,6], [21,6], [22,6], [23,6], [24,6], [25,6], [26,6],
- [19,7], [20,7], [21,7], [22,7], [23,7], [24,7], [25,7], [26,7],
- [19,8], [20,8], [21,8], [22,8], [23,8], [24,8], [25,8], [26,8],
- [19,9], [20,9], [21,9], [22,9], [23,9], [24,9], [25,9], [26,9],
- ]
- this.playerPosition = new Point(0,0);
- this.button = new Button(200, 600, 140, 60, "Start")
- this.button.clickFunction(this.goToGame.bind(this))
- this.optionButtons = [];
- this.optionButtons.push(new Button(30, 30, 60, 60, "1"))
- this.optionButtons.push(new Button(30, 100, 60, 60, "2"))
- this.optionButtons.push(new Button(30, 170, 60, 60, "3"))
- this.optionButtons.push(new Button(30, 240, 60, 60, "4"))
- this.optionButtons[0].clickFunction(() => { this.changeBody(1); })
- this.optionButtons[1].clickFunction(() => { this.changeHair(1); })
- this.optionButtons[2].clickFunction(() => { this.changeTop(1); })
- this.optionButtons[3].clickFunction(() => { this.changeBottom(1); })
- this.wasChanged = false
- }
- init(self) {
- let characterData = JSON.parse(localStorage.getItem('teetopia-player'))
- let body = this.allBodies[0]
- let wearing = this.allTops[0]
- let wearingBottom = this.allBottoms[0]
- let hr = this.allHairs[0]
- if(characterData) {
- body = characterData.bodySprite ?? this.allBodies[0]
- this.bodyType = this.allBodies.findIndex(b => b.toString() == body.toString()) ?? 0
- wearing = characterData.topSprite ?? this.allTops[0]
- this.top = this.allTops.findIndex(t => t.toString() == wearing.toString()) ?? 0
- wearingBottom = characterData.bottomSprite ?? this.allBottoms[0]
- this.bottom = this.allBottoms.findIndex(b => b.toString() == wearingBottom.toString()) ?? 0
- hr = characterData.hairSprite ?? this.allHairs[0]
- this.hair = this.allHairs.findIndex(h => h.toString() == hr.toString()) ?? 0
- }
- this.character = this.characterAtlas.getDrawableSprite(body[0], body[1])
- this.clothingTop = this.characterAtlas.getDrawableSprite(wearing[0], wearing[1])
- this.clothingBottom = this.characterAtlas.getDrawableSprite(wearingBottom[0], wearingBottom[1])
- this.characterHair = this.characterAtlas.getDrawableSprite(hr[0], hr[1])
- }
- draw(ctx, scaledCanvas) {
- this.canvasBounds = scaledCanvas.bounds;
- this.camera.draw(ctx, scaledCanvas, () => {
- ctx.save()
- ctx.translate(this.playerPosition.x, this.playerPosition.y)
- this.character.draw(ctx, scaledCanvas)
- this.clothingBottom.draw(ctx, scaledCanvas)
- this.clothingTop.draw(ctx, scaledCanvas)
- this.characterHair.draw(ctx, scaledCanvas)
- ctx.restore()
- })
- this.button.setPosition(this.canvasBounds.width /2, this.canvasBounds.height *(7/8))
- this.button.draw(ctx, scaledCanvas)
- this.optionButtons.forEach((button => {
- button.draw(ctx, scaledCanvas)
- }))
- }
- update(delta) {
- this.camera.update(delta);
- this.tweenManager.update()
- }
- enter() {
- this.init(this.stateMachine.getState("view"))
- this.registeredEvents["click"] = this.onClick
- this.registeredEvents["resize"] = this.onResize
- this.registeredEvents["keyup"] = this.onKeyUp
- this.registeredEvents["mousemove"] = this.onMouseMove
- this.registeredEvents["mousedown"] = this.onMouseDown
- for(let index in this.registeredEvents) {
- window.addEventListener(index, this.registeredEvents[index].bind(this))
- }
- this.openLoginWindow()
- }
- leave() {
- for(let index in this.registeredEvents) {
- window.removeEventListener(index, this.registeredEvents[index])
- }
- this.registeredEvents = {}
- this.tweenManager.clear()
- }
- onClick() {
- }
- onMouseMove(event) {
- document.body.style.cursor = "default"
- this.button.mouseMove(event)
- this.optionButtons.forEach((button) => {
- button.mouseMove(event)
- })
- }
- onMouseDown(event) {
- this.button.mouseDown(event)
- this.optionButtons.forEach((button) => {
- button.mouseDown(event)
- })
- }
- onFinish() {
- }
- onResize() {
- }
- onKeyUp(event) {
- switch(event.key) {
- case "!":
- this.changeBody(-1)
- break;
- case "1":
- this.changeBody(1)
- break;
- case "@":
- this.changeHair(-1)
- break;
- case "2":
- this.changeHair(1)
- break;
- case "#":
- this.changeTop(-1)
- break;
- case "3":
- this.changeTop(1)
- break;
- case "$":
- this.changeBottom(-1)
- break;
- case "4":
- this.changeBottom(1)
- break;
- case "E":
- let characterData = JSON.parse(localStorage.getItem('teetopia-player'))
- let roomFile = "room5"
- if (characterData) {
- roomFile = characterData.room ?? "room5"
- }
- window.location = `./editor.html?room=${roomFile}`
- break;
- }
- }
- changeBody(direction) {
- [this.bodyType, this.character] = this.spriteCycle(this.bodyType, direction, this.allBodies, this.characterAtlas)
- }
- changeHair(direction) {
- [this.hair, this.characterHair] = this.spriteCycle(this.hair, direction, this.allHairs, this.characterAtlas)
- }
- changeTop(direction) {
- [this.top, this.clothingTop] = this.spriteCycle(this.top, direction, this.allTops, this.characterAtlas)
- }
- changeBottom(direction) {
- [this.bottom, this.clothingBottom] = this.spriteCycle(this.bottom, direction, this.allBottoms, this.characterAtlas)
- }
- spriteCycle(tracker, direction, collection, atlas) {
- this.wasChanged = true
- tracker += direction
- if(tracker < 0) { tracker += collection.length}
- tracker %= collection.length
- let spritePosition = collection[tracker]
- return [tracker, atlas.getDrawableSprite(spritePosition[0], spritePosition[1])]
- }
- goToGame() {
- let characterData = JSON.parse(localStorage.getItem('teetopia-player'))
- if(!characterData || this.wasChanged) {
- characterData = {}
- characterData["bodySprite"] = this.allBodies[this.bodyType]
- characterData["topSprite"] = this.allTops[this.top]
- characterData["bottomSprite"] = this.allBottoms[this.bottom]
- characterData["hairSprite"] = this.allHairs[this.hair]
- }
- localStorage['teetopia-player'] = JSON.stringify(characterData)
- this.stateMachine.transitionTo("play")
- }
- async register(username, password, displayname) {
- let registerRequest = {
- email: username,
- password: password,
- displayname: displayname
- }
- let registerResponse = await new AsyncDataWriter().post("./api/login/register", registerRequest);
- if (registerResponse.responseType != 200) {
- throw new Error(registerResponse.responseMessage)
- }
- }
- async login(username, password) {
- let loginRequest = {
- username: username,
- password: password,
- }
- let postResponse = await new AsyncDataWriter().post("./api/login", loginRequest);
- if (postResponse.responseType != 200) {
- throw new Error(postResponse.responseMessage)
- }
- localStorage.setItem('teetopia-session', JSON.stringify(postResponse));
- }
- async openLoginWindow() {
- let sessionString = localStorage.getItem('teetopia-session');
- if(sessionString) {
- let sessionData = JSON.parse(sessionString)
-
- let response = await new AsyncDataWriter().post('./api/login/session', {token: sessionData.token})
- if(response.responseType == 200) {
- //TODO: load user data
- return
- }
- }
- let loginWindow = await new AsyncDataReader().readDOM('./html/login.html')
- window.document.body.appendChild(loginWindow)
- window.document.getElementById("login").addEventListener("click", async () => {
- try {
- await this.login(
- window.document.getElementById("email").value,
- window.document.getElementById("password").value,
- )
- window.document.body.removeChild(loginWindow)
- } catch (e) {
- window.document.getElementById("login-error").innerHTML = e.message
- }
- })
- window.document.getElementById("register").addEventListener("click", async () => {
- try {
- await this.register(
- window.document.getElementById("email").value,
- window.document.getElementById("password").value,
- window.document.getElementById("email").value,
- )
- await this.login(
- window.document.getElementById("email").value,
- window.document.getElementById("password").value,
- )
- window.document.body.removeChild(loginWindow)
- } catch (e) {
- window.document.getElementById("login-error").innerHTML = e.message
- }
- })
- window.document.getElementById("forgot").addEventListener("click", event => {
- window.document.body.removeChild(loginWindow)
- })
- Array.from(window.document.getElementsByClassName("login-close")).forEach(element => {
- element.addEventListener("click", event => {
- window.document.body.removeChild(loginWindow)
- })
- })
- }
- }
|