dop2000's Forum Posts

  • Border 50 seems too much for cell size 16. Read about cell and border size:

    construct.net/en/make-games/manuals/construct-3/behavior-reference/pathfinding

  • Most likely the event where you play the audio file is repeated on every tick. So the audio is repeated as well.

    Give this audio a tag and add a condition checking that the tag is NOT playing.

    Audio tag "tagname" is NOT playing : Audio play Sound with "tagname"
    
  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • if, for example, "simulate right" and "simulate down" at happening at the same time then the character should move down-right at a 45 deg angle. Not sure why your solution doesn't do that.

    What do you mean? It works like that in my example.

  • This happens to me too sometimes.

  • Also, if I copy the enemy function control group directly into the level 2 event sheet, the enemy works fine.

    You mentioned that the all levels share the same event sheet?

    If the enemy code is on a different event sheet, you need to include it into other sheets. Right-click on an empty space and choose "Include event sheet".

  • I don't understand your question, but you need to swap the conditions in the sub-event.

  • Try enabling "Unbounded scrolling" in layout properties.

    Make sure that there is only one object with ScrollTo behavior.

  • This will pick cards which name starts with the typed text:

    System Pick By Evaluate Cards: find(lowercase(Cards.Name), lowercase(Search.text))=0

    If you want to compare any part of the name:

    System Pick By Evaluate Cards: find(lowercase(Cards.Name), lowercase(Search.text))>=0

  • "Text is Cards.Name" condition doesn't pick cards. It only checks the name of the first card.

    In order to pick cards, you need to swap it:

    Cards compare variable Name=lowercase(Search.text) : Cards set visible
    Cards compare variable Name≠lowercase(Search.text) : Cards set invisible
    

    But if the name can contain uppercase and lowercase characters and you want to ignore the case, you'll have to use System Pick condition.

    System Pick By Evaluate Cards, lowercase(Cards.Name)=lowercase(Search.text) : Cards set visible
    System Pick By Evaluate Cards, lowercase(Cards.Name)<>lowercase(Search.text) : Cards set invisible
    
  • Mouse.x=oldX
    Mouse.y=oldY : Mouse not moving
    
    Else : Mouse is moving
    
    On every tick : Set oldX to Mouse.x, Set oldY to Mouse.Y
    
  • Then what should I use? For each?

    Depends on the task - For Each, Timer behavior, state machine. But "Trigger once" will only cause bugs when you use it like that.

  • The "Lookup Variables" idea is interesting, but setting it up must be a chore.

    Here are my tips:

    1. In all my big projects, I create a AudioPlay function and call it whenever I need to play a sound, instead of using the "Play" action directly. This makes it easy to modify the entire sound system later. For example, you can quickly implement a global volume setting or adjust how audio tags are named.

    2. Similarly, I use a single _LOG function for console logging. This allows me to disable all logs before publishing the game.

    3. Another logging tip: right-clicking anywhere prints all objects under mouse cursor to the console. This is incredibly useful in large games with thousands of objects, many of which are hidden. I used to waste a lot of time manually searching for the right instance in the debugger.

    Here is the code:

    const excludeFamilies = true;
    
    const results = []; // Collect results in an array
    
    for (const objectTypeName in runtime.objects) {
    
    	const allInstances = runtime.objects[objectTypeName].getAllInstances();
     const filteredInstances = allInstances.filter((e) => e.layer && e.layer.name);
    
    	var idx=0;
    	for(var i=0; i<filteredInstances.length; i++) {
    		const instance = filteredInstances[i];
    		const layerIndex = instance.layer.index;
     const x = runtime.objects.Mouse.getMouseX(layerIndex);
     const y = runtime.objects.Mouse.getMouseY(layerIndex);
    
    		const left = instance.getBoundingBox().left;
     const top = instance.getBoundingBox().top;
     const right = instance.getBoundingBox().right;
     const bottom = instance.getBoundingBox().bottom;
    
     // Check if the mouse cursor is within the instance's bounding box
    		// If excludeFamilies=true, duplicate UIDs will be skipped
    		if (excludeFamilies===false || !results.some(record => record.UID === instance.uid)) {
    			if (x >= left && x <= right && y >= top && y <= bottom) {
    				// console.log(`${objectTypeName}\t\tLayer: ${instance.layer.name},\t\tUID: ${instance.uid}`);
    					results.push({
    						Object: objectTypeName,
    						Layer: instance.layer.name,
    						UID: instance.uid,
    						IID: idx,
    						Visible: instance.isVisible,
    						Collisions: instance.isCollisionEnabled || "",
    						Animation: (instance.animation ? (instance.animation.name+":"+instance.animationFrame) : "")
    					});
    
    			}
    		}
    		idx++;
    
     }
    }
    
    console.table(results);

    4. My final logging tip: I created an addon (which, unfortunately, won't work with SDK2) that adds event sheet names and event numbers to all log messages. It also allows to disable logging in the entire project. I wish the Browser object had built-in settings for this.

  • Remove "Trigger once" condition. Never use it with objects that have multiple instances.

  • Here is my attempt:

    dropbox.com/scl/fi/vbfmptsy0qdcl823c9kaw/8Direction_Gamepad.c3p

    Sliding, acceleration, deceleration - all work. The speed also changes based on how far you tilt the stick.

  • You can use "Simulate control" action. It will only work for 8 directions though, as the behavior name suggests.

    Another option is to use vectors and handle acceleration/deceleration with events.