rhg1968's Forum Posts

  • It's not supported yet, but you could use runtime.callFunction() to call a function in the event sheet to set the animation. You could pass the uid so you can select the object in the function.

  • Does this mean that if we add the js files to the imported files section that command/syntax checking will happen like in the scripts folder ?

  • Sorry I never added to this thread.

    The issue for me was taken care with R156 as shown in the release notes for that version.

    Possible runtime crash creating instances not placed anywhere in project (regression in r155).

    In R155 I fixed the issue by putting instances of all my objects on the layout and then destroying them on the start of the layout.

    Hope that helps.

  • I really like the approach of LoadScripts. I will change things over to use that instead of relying on folder order.

  • What I have found so far is that it groups everything alphabetically when adding scripts. So if I add a base class after I add the super class, it fails because the base didn't load. If I then create a sub folder called "A" and move the base class into that folder, it's not read before the super class and everything loads.

    Not sure if they'll give us more flexibility with this later on, but you can make it work.

    I have almost reworked my entire game into mostly JavaScript and that's how I worked around it.

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • ok, thanks.

    I will try to create a small project to see if I can duplicate it and file a bug. I know someone else has run into this issue also. I'll see what I can come up with.

  • I posted this comment on the release comments so not sure if I should leave it here. Let me know if I should delete it.

  • I went back to an old version of my game without any JavaScript scripting and I get the same error.

  • I have to do a little more research to see if I can create a small example of this issue I am seeing and post in the bug tracker.

    I have coded a large portion of my game in java script and it has been working well in R154 and stil does. As soon as I switch to r155 I get the following error in the console after it navigates from my boot layout to the title layout.

    Tagged:

  • Ashley

    Didn't know if you missed this or it's coming, but I noticed you added the IStotage documentation, but it doesn't look like you added the storage property on the runtime documentation.

    I'm just bringing it up because it's working great and I'm really loving the new scripting features.

    Thanks

    Tagged:

  • Just thought I would share a simple class for using vectors if you want to use them. It doesn't all functionality it could, but I think it works pretty well in the context of 2D games.

    Also the philosophy of the member functions is that they modify the existing vector where as the static methods don't modify the original and create a new vector.

    class RGVector
    {
    	constructor(x=0, y=0){
    		this.x=x;
    		this.y=y;
    	}
    	
    	add(v1){
    		this.x += v1.x;
    		this.y += v1.y;
    		
    		return this;
    	}
    	
    	addPoints(x, y) {
    		this.x += x;
    		this.y += y;
    		
    		return this;
    	}
    	
    	sub(v1) {
    		this.x -= v1.x;
    		this.y -= v1.y;
    		
    		return this;
    	}
    	
    	subPoints(x,y) {
    		this.x -= x;
    		this.y -= y;
    		
    		return this;
    	}
    	
    	mult(scalar) {
    		this.x *= scalar;
    		this.y *= scalar;
    		
    		return this;
    	}
    	
    	multX(scalar) {
    		this.x *= scalar;
    		
    		return this;
    	}
    	
    	multY(scalar) {
    		this.y *= scalar;
    		
    		return this;
    	}
    	
    	div(scalar) {
    		this.x /= scalar;
    		this.y /= scalar;
    		
    		return this;
    	}
    	
    	divX(scalar) {
    		this.x /= scalar;
    		
    		return this;
    	}
    	
    	divY(scalar) {
    		this.y /= scalar;
    		
    		return this;
    	}
    	
    	mag() {
    		return Math.sqrt((this.x*this.x) + (this.y*this.y));
    	}
    	
    	normalize() {
    		const m = this.mag();
    		
    		if (m>0) {
    			return this.div(m);
    		}
    		else
    		{
    			return this;
    		}
    	}
    	
    	clone() {
    		return new RGVector(this.x, this.y);
    	}
    	
    	limitTo(value) {
    		this.normalize().mult(value);
    		
    		return this;
    	}
    	
    	angleFrom(v1) {
    		return Math.acos(this.dotProduct(v1) / (Math.abs(this.mag()) * 
    				Math.abs(v1.mag())));
    	}
    	
    	dotProduct(v1){
    		return (this.x * v1.x) + (this.y * v1.y);
    	}
    	
    	invertX() {
    		this.x *= -1;
    		
    		return this;
    	}
    	
    	invertY() {
    		this.y *= -1;
    		
    		return this;
    	}
    	
    	invert() {
    		this.invertX();
    		this.invertY();
    		
    		return this;
    	}
    	
    	static Add(v1, v2)
    	{
    		return v1.clone().add(v2);
    	}
    	
    	static AddPoints(v1, x, y)
    	{
    		return v1.clone().addPoints(x,y);
    	}
    	
    	static Sub(v1, v2) {
    		return v1.clone().sub(v2);
    	}
    	
    	static SubPoints(v1, x, y) {
    		return v1.clone().subPoints(x,y);
    	}
    	
    	static Mult(v1, scalar) {
    		return v1.clone().mult(scalar);
    	}
    	
    	static MultX(v1, scalar) {
    		return v1.clone().multX(scalar);
    	}
    	
    	static MultY(v1, scalar) {
    		return v1.clone().multY(scalar);
    	}
    	
    	static Div(v1, scalar) {
    		return v1.clone().div(scalar);
    	}
    	
    	static DivX(v1, scalar) {
    		return v1.clone().divX(scalar);
    	}
    	
    	static DivY(v1, scalar) {
    		return v1.clone().divY(scalar);
    	}
    	
    	static Mag(v1) {
    		return v1.mag();
    	}
    	
    	static Normalize(v1) {
    		return v1.clone().normalize();
    	}
    	
    	static Clone(v1) {
    		return v1.clone();
    	}
    	
    	static LimitTo(v1, value) {
    		return v1.clone().limitTo(value);
    	}
    	
    	static AngleFrom(v1, v2) {
    		return v1.angleFrom(v2);
    	}
    	
    	static InvertX(v1) {
    		return v1.clone().invertX();
    	}
    	
    	static InvertY(v1) {
    		return v1.clone().invertY();
    	}
    	
    	static Invert(v1) {
    		return v1.clone().invertX().invertY();
    	}
    }
    

    Tagged:

  • This isn't perfect, but I thought somebody may be interested in using this as a base for a code only local storage solution that is indexDB based, like the construct3 local storage plugin. It also wraps the indexDB functions in promises so that you can use async await.

    First I'll show the class that provides the functionality and then a small sample of it being used.

    class RGLocalStorage
    {
    	constructor(){
    		this.indexDB = globalThis.indexedDB || globalThis.mozIndexedDB ||
    			globalThis.webkitIndexedDB || globalThis.msIndexedDB;
    		
    		if (!this.indexDB) {
    			throw "IndexDB is not supported in this browser!";
    		}
    		
    		this.db=undefined;
    	}
    	
    	static Initialize(){
    		return new Promise((resolve, reject)=>{
    			const dblocal = new RGLocalStorage();
    		
    			const openReq = dblocal.indexDB.open('rgbz', 1);
    			
    			openReq.onerror = (event)=>{
    				reject('Error opening database odii - ' +
    					 event.target.errorCode);
    			};
    			
    			openReq.onsuccess = (event)=>{
    				dblocal.db = event.target.result;
    				resolve(dblocal);
    			};
    			
    			openReq.onupgradeneeded = (event)=>{
    				event.target.result.createObjectStore("rglocalstorage");
    			};
    		});
    	}
    	
    	put(key, obj) {
    		return new Promise((resolve, reject)=>{
    			const transaction = this.db.transaction(["rglocalstorage"], "readwrite");
    			
    			transaction.onerror = (event)=>{
    				reject({
    					result: false,
    					message: event.target.errorCode
    				});
    			}
    			
    			const objStore = transaction.objectStore("rglocalstorage");
    			
    			const operation = objStore.put(obj, key);
    			
    			operation.onsuccess = (event)=>{
    				resolve({
    					result: true,
    					message: 'success'
    				});
    			};
    			
    			operation.onerror =(event)=>{
    				reject({
    					result: false,
    					message: event.target.errorCode
    				});
    			}
    		});
    	}
    	
    	clearAll() {
    		return new Promise((resolve, reject)=>{
    			const transaction = this.db.transaction(["rglocalstorage"], "readwrite");
    			
    			transaction.onerror = (event)=>{
    				reject({
    					result: false,
    					message: event.target.errorCode
    				});
    			}
    			
    			const objStore = transaction.objectStore("rglocalstorage");
    			
    			const operation = objStore.clear();
    			
    			operation.onsuccess = (event)=>{
    				resolve({
    					result: true,
    					message: 'success'
    				});
    			};
    			
    			operation.onerror =(event)=>{
    				reject({
    					result: false,
    					message: event.target.errorCode
    				});
    			}
    		});
    	}
    	
    	delete(key) {
    		return new Promise((resolve, reject)=>{
    			const transaction = this.db.transaction(["rglocalstorage"], "readwrite");
    			
    			transaction.onerror = (event)=>{
    				reject({
    					result: false,
    					message: event.target.errorCode
    				});
    			}
    			
    			const objStore = transaction.objectStore("rglocalstorage");
    			
    			const operation = objStore.delete(key);
    			
    			operation.onsuccess = (event)=>{
    				resolve({
    					result: true,
    					message: 'success'
    				});
    			};
    			
    			operation.onerror =(event)=>{
    				reject({
    					result: false,
    					message: event.target.errorCode
    				});
    			}
    		});
    	}
    	
    	get(key) {
    		return new Promise((resolve, reject)=>{
    			const transaction = this.db.transaction(["rglocalstorage"], "readonly");
    			
    			transaction.onerror = (event)=>{
    				reject({
    					result: false,
    					message: event.target.errorCode
    				});
    			}
    			
    			const objStore = transaction.objectStore("rglocalstorage");
    			
    			const operation = objStore.get(key);
    			
    			operation.onsuccess = (event)=>{
    				resolve({
    					result: event.target.result,
    					message: 'success'
    				});
    			};
    			
    			operation.onerror =(event)=>{
    				reject({
    					result: false,
    					message: event.target.errorCode
    				});
    			}
    		});
    	}
    	
    	getAll() {
    		return new Promise((resolve, reject)=>{
    			const transaction = this.db.transaction(["rglocalstorage"], "readonly");
    			
    			transaction.onerror = (event)=>{
    				reject({
    					result: false,
    					message: event.target.errorCode
    				});
    			}
    			
    			const objStore = transaction.objectStore("rglocalstorage");
    			
    			const operation = objStore.getAll();
    			
    			operation.onsuccess = (event)=>{
    				resolve({
    					result: event.target.result,
    					message: 'success'
    				});
    			};
    			
    			operation.onerror =(event)=>{
    				reject({
    					result: false,
    					message: event.target.errorCode
    				});
    			}
    		});
    	}
    }
    

    Here is some script start up code I am using to store stuff in "local storage". I am using an async await with a try catch structure. I am also showing awaiting multiple items on startup.

    let config,rgLocalStorage;
    
    runOnStartup(async runtime =>
    {
    	// Code to run on the loading screen
    	
    	try {
    		[config, rgLocalStorage] = await Promise.all([
    				runtime.assets.fetchJson("state.json"),
    				RGLocalStorage.Initialize()
    				]);
    		
    //		const result = await rgLocalStorage.put('Stuff', {name:'Rob'});
    //		const result = await rgLocalStorage.getAll();
    //		const result = await rgLocalStorage.get('Stuff');
    //		const result = await rgLocalStorage.delete('Stuff');
    //		const result = await rgLocalStorage.clearAll();
    //		console.log(result);
    	}
    	catch (e) {
    		console.log(e);
    		throw e;
    	}
    });
    

    Tagged:

  • Ashley

    I noticed in the ghost shooter example you access the current layout directly off of the instance of a monster in the IsOutsideLayout. Looking at the documentation I don't see that a reference is provided to layout on an instance. Am I missing something or was it just missed adding it to the documentation ?

    Either way, the scripting feature is really amazing and I can't wait to see it as it develops further.

  • I agree that having functions to access the other layers in the project would be good. Good to know that it's a possibility in the future.

    Thank you !!!!!!

  • Ashley

    I see, in the Ghost Shooter example, that you reference the layout property on the runtime to set events to run on the start of the layout. According to the documentation the layout property refers to the current layout. If I have more than one layout is there a way to assign different events to the start of other layouts in the project ?

    Tagged: