rhg1968's Forum Posts

  • 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:

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • 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:

  • It looks like your mouse event is a sub event of the text is 16 condition check.This means the mouse click will only trigger when the text is equal to 16 and I'm not sure if that was your intention.

  • Ashley

    Thanks. I know you just implemented the basics of scripting so far, but what you have is amazing. Keep up the great work it is very much appreciated.

  • I'm sure there will more functions added to the official API, but one way, if anyone is interested, is to use functions to pass information from the event sheet to the script and vice versa.

    You can use globalThis.c3_callFunction("FunctionName", []); //The array is the function parameters.

    You can also get a hold of the full addon sdk, but I think that defeats the purpose of a nice clean API for accessing everything and can lead to issues if the inner workings change.

    I'm sure this functionality and a lot more will be added to the official API, but in the meantime you play around with using functions.

    Tagged:

  • Android exports on my galaxy s8+ didn't work, always a black screen, until chrome on my android device updated to 74. Once that happened it worked perfectly on r148 and r149.

    I think you will see the black screen on a device that chrome hasn't been upgraded. What version of chrome are you running on the actual device ?

  • Just a quick question. I have an a plugin I created a while ago for the c3 runtime and it used variadic parameters. I see the warning in the console.

    My question is, you said this wasn't supported and that's the issue with using features in the SDK not documented. The only reason I used it in my plugin is because it's mentioned in the SDK manual as isVariadicParameters.

    So I wanted to make sure that this is indeed the functionality that is being depreciated.