UNPKG

jsgam

Version:

JavaScript Graphic Adventure Maker

322 lines (271 loc) 9.59 kB
import {boxesIntersect,collision,closestPoint} from '../collisions.js'; class GameObject{ constructor(){ this.sprite=null; this.game=null; this.action=null; } build(){ if(this.config.Description===undefined){ this.config.Description=this.game.data.texts.NoDescription; } //Configure the sprite's object if(this.config.Texture){ //Generate a static object from a texture this.sprite=new PIXI.Sprite.from(PIXI.Texture.from(this.config.Texture)); }else if(this.config.Area){ //For invisible objects this.sprite=new PIXI.Sprite.from(PIXI.Texture.EMPTY); this.sprite.hitArea=new PIXI.Polygon(this.config.Area); }else if(this.config.Animation){ //Animated objects let spritesheet=this.game.files.resources[this.config.Animation.Name].spritesheet; let frames = []; for (var i = 0; i < spritesheet._frameKeys.length; i++) { frames.push(PIXI.Texture.from(spritesheet._frameKeys[i])); } this.sprite=new PIXI.extras.AnimatedSprite(frames); this.animationSpeed=this.config.Animation.Speed; this.play(); } //Texture to show when the object is inside the inventory if(this.config.Icon){ this.icon=PIXI.Texture.from(this.config.Icon); } //Position of the object in the screen if(this.config.Position){ this.sprite.x=this.config.Position[0]; this.sprite.y=this.config.Position[1]; } //Size of the object if(this.config.Size){ this.sprite.scale.set(this.config.Size) } if(this.config.Mirror){ this.flip(); } //Configure the anchor (origin point of the object) if(!this.config.Area)this.sprite.anchor.set(0.5,1); //Configure the layer for the z-order if(this.config.Layer==="Top") this.sprite.parentLayer=this.game.layerTop; else if(this.config.Layer==="Bottom") this.sprite.parentLayer=this.game.layerBottom; else this.sprite.parentLayer = this.game.layer; this.holding=false; this.timeoutID; //Game object events this.sprite.interactive=true; this.sprite.buttonMode=true; if(this.config.Area!==undefined){ this.sprite.on('pointerdown', this.touchArea.bind(this)) .on('pointerup', this.releaseArea.bind(this)) .on('pointerupoutside', this.releaseArea.bind(this)); }else{ this.sprite.on('pointerdown', this.touch.bind(this)) .on('pointermove', this.move.bind(this)) .on('pointerup', this.release.bind(this)) .on('pointerupoutside', this.release.bind(this)); } if(this.config.Interactive!==undefined) this.setInteraction(this.config.Interactive); } hide(){ this.sprite.visible=false; } show(){ this.sprite.visible=true; } setpos(x,y){ this.sprite.x=x; this.sprite.y=y; } flip(){ this.sprite.scale.x*=-1; } changeTexture(texture){ this.sprite.texture=new PIXI.Texture.from(texture) } hold(){ this.holding=true; } //Invisible object touch begins touchArea(event){ if(this.game.activeObject===null && !this.game.player.lock){ this.game.activeObject=this; this.interaction = event.data; this.action=null; if(this.timeoutID) clearTimeout(this.timeoutID); this.timeoutID=setTimeout(this.hold.bind(this), this.game.holdTime); this.touchedPos=this.interaction.getLocalPosition(this.game.app.stage); } } //Invisible object touch ends releaseArea(){ if(this.timeoutID) clearTimeout(this.timeoutID); if(this.interaction){ let moveTo=this.interaction.getLocalPosition(this.game.app.stage); if(collision(moveTo,this.sprite)){ if(this.interaction.button===2 || this.holding){ if(this.config.Door){ let newPos=closestPoint(this.config.Area,moveTo); moveTo=newPos; }else if(this.config.Use!==undefined){ this.game.activePuzzle=this.game.puzzles[this.config.Use]; } this.action="Use"; }else if(this.config.Door && this.config.Door.NoLook){ this.action="Use"; }else{ this.action="Look"; } } if(this.action!==null){ this.game.player.endAction=this.action; if(this.config.InteractionPoint) moveTo={x:this.config.InteractionPoint[0],y:this.config.InteractionPoint[1]}; this.game.player.move(moveTo); }else{ this.cancel(); } if(this.game.player.touched) this.game.player.touched=false; this.holding=false; this.interaction = null; this.touchedPos=null; } } //Object touch begins touch(event){ if(this.game.activeObject===null && !this.game.player.lock){ this.game.activeObject=this; this.action=null; this.posX = this.sprite.x; this.posY = this.sprite.y; this.interaction = event.data; this.sprite.alpha = 0.5; this.dragging = true; if(this.timeoutID) clearTimeout(this.timeoutID); this.timeoutID=setTimeout(this.hold.bind(this), 1000); this.oldParent=this.sprite.parent; this.depthGroup=this.sprite.parentLayer; if(this.sprite.parentLayer !== this.game.layerUI) this.sprite.parentLayer = this.game.layerUI; } } //Object is being dragged move(){ if (this.dragging && !this.config.Lock) { this.sprite.setParent(this.game.app.stage); var newPosition = this.interaction.getLocalPosition(this.sprite.parent); let bounds=this.sprite.getBounds(); this.sprite.x = newPosition.x; this.sprite.y = newPosition.y; //We can only move the object inside the stage //if(newPosition.x>bounds.width/2 && newPosition.x<this.game.width-bounds.width/2) this.sprite.x = newPosition.x; //if(newPosition.y>bounds.height && newPosition.y<this.game.height) this.sprite.y = newPosition.y; } } //Object drag/touch ends release(){ if(this.timeoutID) clearTimeout(this.timeoutID); if(this.interaction){ let moveTo; if(this.config.InteractionPoint){ moveTo={x:this.config.InteractionPoint[0],y:this.config.InteractionPoint[1]}; }else{ moveTo={x:this.posX,y:this.posY}; } //Check if we take it if(collision(this.sprite,this.game.inventory.icon) && this.config.Take){ this.action="Take"; //Check if we look it }else if(this.interaction.button===2 || this.holding){ if(this.config.Use!==undefined) this.game.activePuzzle=this.game.puzzles[this.config.Use]; this.action="Use"; }else if(this.config.Door!==undefined){ if(this.config.Door.NoLook) this.action="Use"; }else{ this.action="Look"; } if(this.game.player.touched) this.game.player.touched=false; this.sprite.x = this.posX; this.sprite.y = this.posY; this.sprite.alpha = 1; this.sprite.parentLayer = this.depthGroup; this.sprite.setParent(this.oldParent); this.holding=false; this.interaction = null; this.dragging = false; if(this.action!==null){ this.game.player.endAction=this.action; this.game.player.move(moveTo); }else{ this.cancel(); } } } //Check collision between objects hit(){ let found=null; let i; //First check the collision between active scene's objects let objectsArray=this.game.activeScene.config.Objects; if(objectsArray!==undefined){ for(i=0;i<objectsArray.length;i++){ if(collision(this.sprite,this.game.objects[objectsArray[i]].sprite) && this.config.Name!==objectsArray[i]){ found=objectsArray[i]; break; } } } //Check if the collision is between inventory objects objectsArray=this.game.inventory.objects; for(i=0;i<objectsArray.length;i++){ if(collision(this.sprite,this.game.objects[objectsArray[i]].sprite) && this.config.Name!==objectsArray[i]){ found=objectsArray[i]; break; } } //Check the collision a character let charsArray=this.game.activeScene.config.Characters; if(charsArray!==undefined){ for(i=0;i<charsArray.length;i++){ if(collision(this.sprite,this.game.npcs[charsArray[i]].sprite) && this.config.Name!==charsArray[i]){ found=charsArray[i]; break; } } } return found; } //Object action is canceled or ended cancel(){ this.game.activeObject.action=null; this.game.activeObject=null; } setInteraction(value){ this.sprite.interactive=value; } //Add the object to a given scene add(scene){ this.game.scenes[scene].container.addChild(this.sprite); this.game.scenes[scene].config.Objects.push(this.config.Name); } //Remove objects from game remove(){ this.sprite.parent.removeChild(this.sprite); //Check if we remove an object which is in an scene let scenesArray=Object.values(this.game.scenes) let i; let scenesLength=scenesArray.length; for(i=0;i<scenesLength;i++){ if(scenesArray[i].config.Objects!==undefined && scenesArray[i].config.Objects.includes(this.config.Name)){ let tmpIndex=scenesArray[i].config.Objects.indexOf(this.config.Name); scenesArray[i].config.Objects.splice(tmpIndex,1); } } //Check if the object to remove is inside the inventory if(this.game.inventory.objects.includes(this.config.Name)){ this.game.inventory.remove(this.config.Name); } } } export default GameObject;