How can i make world environment nodes connect with signals across and between scenes to change atmosphere when entering area nodes - godot

wont work bidirectionally to make world environment scenes to the levels link with atmosphere change, here is the code
`
extends Spatial
#RedFell.gd
export onready var Forest = $"/root/GlobalWorldEnvironment"
export onready var RedFell = $"/root/RedFellEnvironment"
signal player_entered_forest
func _ready():
var player_desert = get_tree().get_root().find_node("RedFell", true, false)
player_desert.connect("player_entered_forest",self, "_player_entered_desert")
func _on_DesertArea_body_entered(body):
if body.is_in_group("Player"):
Forest.environment = RedFell.environment
emit_signal("player_entered_forest")
print(body)
func _on_DesertArea_body_exited(body):
if body.is_in_group("Player"):
pass
func _player_entered_desert():
print("Player entered Desert")
Forest.environment = RedFell.environment
currently this changes the forest level to the desert atmosphere world environment, but cannot make it bidirectional with this
extends Spatial
##Forest.gd
export onready var Forest = $"/root/GlobalWorldEnvironment"
export onready var RedFell = $"/root/RedFellEnvironment"
signal player_entered_desert
func _ready():
var player_desert = get_tree().get_root().find_node("RedFell", true, false)
player_desert.connect("player_entered_desert",self, "_player_entered_forest")
func _on_ForestArea_body_entered(body):
if body.is_in_group("Player"):
RedFell.environment = Forest.environment
emit_signal("player_entered_desert")
func _on_ForestArea_body_exited(body):
if body.is_in_group("Player"):
pass
func _player_entered_forest():
print("Player entered Desert")
Forest.environment = RedFell.environment
`
I've been trying to get this work but it doesn't change back to the forest when walking back into the forest level

It seems to me that you are losing the reference to the environment in your attempt to swap them.
Store the environments to resource files, and load or preload the one you want instead:
$"/root/GlobalWorldEnvironment".environment = preload("res://path/to/forest_enviroment.tres")

Related

Godot: exported boolean variable is always false

I have a problem with an exported set of boolean variables, flags to enable an Area2D feature:
tool
extends Area2D
signal direction_changed
export(bool) var allow_right
export(bool) var allow_left
export(bool) var allow_up
export(bool) var allow_down
var controlled_component = null
var directions: PoolVector2Array
var direction: Vector2
func _init():
init_directions()
func init_directions():
print_debug(allow_down, allow_left, allow_right, allow_up)
directions = []
if(allow_right):
directions.append(Vector2(1,0))
if(allow_down):
directions.append(Vector2(0,1))
if(allow_left):
directions.append(Vector2(-1,0))
if(allow_up):
directions.append(Vector2(0,-1))
and this results in showing the flags in my Scene inspector:
what I don't get is why if I flag a couple of them like this:
why the print_debug statement results in this:
FalseFalseFalseFalse
Shouldn't two of the bool variables be set to True?
Am I missing something?
You are using a tool script, which runs inside the IDE. Therefore the "_init()" function (where you call "init_directions()" with print_debug) is called when you open a scene with this script for the first time. When you make a change in the inspector, the change will be applied if you save, close the scene and open it again.

Problem with collisions between static and moveable objects with non rectangular outline

As part of work I was told to build a small game in phaser where I have to drag and drop some objects using mouse over some static objects in the scene and make out if the drop was done on the matching static object. The static and the not static objects all have non-rectangular boundaries, so I used Physics editor to draw their boundaries and import them into Phaser. To detect collisions while dragging the object I am using matter callbacks for 'collisionstart' and 'collisionend'. Say for example I am trying to drag an apple onto a tree, as soon as the the apple body collides with the tree outline, 'collisionstart' triggers, but as I move the apple inside the tree boundary 'collisionstart' and 'collisionend' trigger multiple times. So this seems to be an unreliable way to detect overlap between two objects.
Collision code:
var canDrag = this.matter.world.nextGroup();
currentObject = this.matter.add.image(360, 360, 'Carrot', 0, { chamfer: 16 }).setCollisionGroup(canDrag);
currentObject.body.label = 'Carrot';
this.matter.add.mouseSpring({ collisionFilter: { group: canDrag } });
this.matter.world.on('collisionstart', function (event, bodyA, bodyB)
{
if ((bodyA.parent.label == 'Tree') || (bodyB.parent.label == 'Tree')) {
tree.tint = tintColor;
}
});
this.matter.world.on('collisionend', function (event, bodyA, bodyB)
{
if ((bodyA.parent.label == 'Tree') || (bodyB.parent.label == 'Tree')) {
tree.tint = normalColor;
}
});

CaKeyframeAnimation persisting in background after dismissing view controller

Hi I have simple CAShapeLayer animation
let ballFrameAnimation = CAKeyframeAnimation()
aBall.removeFromSuperlayer()
self.view.layer.addSublayer(aBall)
ballFrameAnimation.keyPath = "position"
ballFrameAnimation.duration = 3.0
ballFrameAnimation.calculationMode = kCAAnimationDiscrete
ballFrameAnimation.fillMode = kCAFillModeForwards
ballFrameAnimation.isRemovedOnCompletion = true
ballFrameAnimation.delegate = self
with a callback to keeps it repeating
func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
let name = anim.value(forKey: "name") as? String
if name == "form" {
attachAnimation()
forwardDirection = !forwardDirection
}
However this persists and loops in the background ( at high speed) even when I pop the viewcontroller off the stack. It also shows a memory leak as well on instruments.
#IBAction func unwindDismiss(_ sender: Any) {
aBall.removeAnimation(forKey: "ballAnimation")
aBall.removeFromSuperlayer()
navigationController?.popToRootViewController(animated:true)
dismiss(animated: true, completion: nil)
}
It was simple.
The endless loop animation would not be released by simply dismissing the viewcontroller so it persisted in the background.
By adding a
if navigationController?.topViewController == self {
loop check within the animation did stop cycling.
this fixed not only the accelerating background loops but also the memory leaks. also a warning to fellow NOOBs : when using the instruments repeatedly: close and restart them frequently and also clean builds otherwise you are likely to get bogus leaks.

An object's movement, using sprite.body.moveTo, is interfered with on collision

I am making a platformer, and I want to make something similar to Thwomp from Mario. So it's just an enemy that patrols between two points, and any collision with the player will kill the player.
I do this via Phaser's sprite.body.moveTo. I need to check if the enemy overlaps with the player, so I can trigger the player dying.
The problem is that, when the player and enemy collide, the moveTo is messed up, and the enemy's path is hindered. I took a short video to demonstrate what happens. Video.
Here is the code for when I create the enemy. I use an object group from Tiled for the properties, so thats what all the map.objects.mainObjecets[i] stuff is.
//demons is a phaser group with body enabled.
var demon = demons.create(map.objects.mainObjects[i].x,map.objects.mainObjects[i].y,'demon');
demon.direction = Number(map.objects.mainObjects[i].properties.direction);
demon.distance = Number(map.objects.mainObjects[i].properties.distance);
demon.duration = Number(map.objects.mainObjects[i].properties.duration);
//I tried using stopVelocityOnCollide and immovable to fix the problem, neither one worked
demon.body.stopVelocityOnCollide=false;
demon.body.immovable = true;
demon.body.onMoveComplete.add(moveDemon, this);
game.time.events.add(map.objects.mainObjects[i].properties.delay, function(a) {
a.body.moveTo(a.duration, a.distance, a.direction);
}, this, demon);
And here is the code that runs everytime a movement completes.
function moveDemon(demon) {
game.time.events.add(Phaser.Timer.SECOND * .3, function() { //.3 second delay before moving
demon.direction = 360-demon.direction;
demon.body.moveTo(demon.duration, demon.distance, demon.direction);
}, this);
}
And lastly, here is the code for checking for overlaps
this.physics.arcade.overlap(player,demons,function(){
//This code just moves the player back to the spawn point.
player.x = map.objects.spawn[0].x;
player.y = map.objects.spawn[0].y;
});

Phaser.io - Load objects from Tiled

I'm new to phaser, and for the past few days I've been trying to make a really simple game, platformer-style, where the player must navigate to certain areas before being able to exit the level.
I have the basics running, but now I can't seem to figure out how to check if the player is in those areas.
The relevant part of the code so far is as follows:
var game = new Phaser.Game(800, 600, Phaser.AUTO, "mygame", {
preload: preload,
create: create,
update: update,
render: render
});
function preload() {
game.load.tilemap("questMap", "assets/quest.json", null, Phaser.Tilemap.TILED_JSON);
game.load.image("tilesheet", "assets/tilesheet.png");
game.load.image("npc", "assets/npc.png");
game.load.spritesheet("player", "assets/player.png", 64, 64);
}
var map;
var tileset;
var groundBg;
var props;
var houses;
var houseProps;
var npc;
var ground;
var areas;
var player;
function create() {
game.physics.startSystem(Phaser.Physics.ARCADE);
game.stage.backgroundColor = "#A8DBFF";
map = game.add.tilemap("questMap");
map.addTilesetImage("tilesheet");
map.addTilesetImage("npc");
ground = map.createLayer("ground");
groundBg = map.createLayer("groundbg");
props = map.createLayer("props");
houses = map.createLayer("houses");
houseProps = map.createLayer("houseprops");
npc = map.createLayer("npc");
map.setCollisionBetween(1, 5000);
ground.resizeWorld();
Not too pretty, I know.
I've created the map with tiled and there are a lot of small props and decorative tiles, hence the multiple "map.createLayer()" calls. The only one with collision is the ground layer.
Now, on my Tiled file, I've created an Object layer and drawn small rectangles on the areas I want to check if the player is in. I thought this was going to be an easy process but I can't seem to figure out how to load those areas into Phaser, and then check if the player is within bounds.
Googling has given me some results, but none seem to fit, as they usually cover how to add a sprite to an object, which in this case does not apply.
I simply need that small area to exist and check if the player is there. I've also given names to each of those rectangles in Tiled, via the custom properties tab.
I would try using a transparent image as the area you wish to check if your sprite is over and use
if(sprite1.overlap(transparentImage)){
//do something
}

Resources