I'm kind of a UI buff - every "screen" in my game should transition in/out when it appears or disappears. Because my game is simple in terms of resources, I thought I'd just make each "screen" a CCLayer and define a function for the transitions, leaving everything in memory. It's turning out to be more complicated than I expected.
I think I have two main problems right now:
1) Each "screen" is a CCLayer. This looks fine, but I can't seem to stop receiving touch events, even when they are inactive. Child sprites do not seem to respect the isTouchEnabled property, so I'm hitting invisible buttons all the time.
2) I wrote a custom button class that is basically a sprite with a few separate textures for states. It uses the CCTargetedTouchDelegate protocol. I'm thinking this is a big part of the above problem.
I'm not quite clear on the CCMenu stuff. Is there a tutorial or documentation out there that better explains its designed purpose and how to use it? The documentation for cocos2d doesn't talk at all about what each class does, which makes it much, much harder to properly use the library. Also, when should I use a scene instead of layers? Can I write custom transitions?
I found that if you have multiple layers in a single scene for menus, such as for a main menu (simpler to have a layer for load game, new game, etc. than an entire scene) that if you add all of you buttons as children of the layer; then to stop them from receiving touches, simply move the layer off screen when not in use. Heres an example.
[loadLayer setPosition:CGPointMake(-1000,-1000)];
[settingsLayer setPosition:CGPointMake(-1000,-1000)];
[menuLayer setPosition:CGPointMake(0,0)];
And each time you select a button that would take you to say the load game layer just reverse it for the right layer.
[loadLayer setPosition:CGPointMake(0,0)];
[settingsLayer setPosition:CGPointMake(-1000,-1000)];
[menuLayer setPosition:CGPointMake(-1000,-1000)];
It's more convenient to use CCScenes for menus. All of the children of an inactive CCScene will not receive touch events, so you don't have to manage that behavior. CCScenes also have built-in transitions like a crossfade, but if you're like me, you'll probably just want to run an action to make the scene transition out, then call CCDirector:replaceScene.
Related
So when my player falls off the map, I want the level to reload. I have used an area2d with a collisionshape2d to create an area that will call a function when the player collides with this area. However, when the game is run with this code included, the player will animate through a few frames then the game completely freezes before I can even move the player.
func _on_Area2D_body_entered(body):
get_tree().reload_current_scene()
If I delete this code, or set monitoring to off, and re-run the game it will not freeze.
Below is a screenshot of my level design.
Level design
Any help would be greatly appreciated :) - Is this a bug or am I doing something stupid?
When I set a breakpoint on the get_tree().reload_current_scene() line the following report shows
debugger
does this mean the player is colliding with a tile - If this is the case I don't see how as the program freezes before the player touches the ground.
As I said in the comments, this line:
get_tree().reload_current_scene()
Returns a value.
Now, you have said that 0 is "continuously outputted". In this context 0 means OK, in other words: it was able to reload the scene. The problem is the "continuously" part. It means that the scene reloads and then this code is triggered, and then it reloads again, and then this code is triggered again, and so on.
Now, apparently the Area2D is colliding with the TileMap. That makes sense. If it is a collision between the Area2D and a tile upon loading the scene, you would get the observed behavior. And the way the Area2D and TileMap are positioned in the scene supports the idea.
And about fixing it. I'll give you three solutions, either of these will work, with their drawbacks and caveats:
Don't have the Area2D positioned in a way that intersects non-passable tiles. This is easy to do by moving the Area2D further down, or by removing any tiles that overlap it.
The drawback with this approach is that it is fragile. You may forget in the future and move the Area2D or add tiles or something else that make the problem return. Also, it might not work well with your intended scenario design.
Change the collision_mask and collision_layer in such way that the tiles and the Area2D do not collide. As long as the bits from the mask do not overlap the bits from the layer of the other and viceversa, Godot will not even check for a collision between them.
The main drawback with this approach is that you have limited number of layers.
There is also the fact that it is less intuitive that simply placing things in such a way they don't collide.
To make it easier to work with, assign layers to different kinds of thingsā¦ Go to your Project Settings, on the General Tab, under Layer Names, and 2D Physics, and give them names (e.g. "environment", "enemies", "enemy bullets", "player", "player bullets", "items", "others").
Then you can assign to each object on collision_layer what they are, and on collision_mask set every thing they MUST collide with. With the caveat that Godot will check both ways.
In this case you would set the collision_layer of the player character physics object (the KinematicBody2D) to "player" (or similar), and put the collision_mask of the Area2D to the same, so they collide. Have the collision_layer of the TileMap set to something else (e.g. "environment") that is not in the collision_mask of the Area2D, so the Area2D and the TileMap do not collide. And set the collision_mask of the player character to something that include the layer you set to the TileMap, so the player character also collides with it. I hope that makes sense.
And, of course, you can filter on the Area2D, with a little of code. It can be checking the class, or node group, or the name of the physics body. For example you can insert at the start of the method something like this: if body.name != "player": return. So that it exits the method before it reaches reload_current_scene unless it is the correct physics body.
The drawback with this approach is that it is still checking and registering the collision, so it has worse performance that using collision_mask and collision_layer. But it will work, and it will perform OK for a small to mid sized game.
For more complex situations, you may employ a combination of these approaches (because, as I said, there is a limited number of layers, so you need to add filtering on top of it). I have a more detailed explanation of how to setup physics objects, including the techniques mentioned here, in another answer.
I'm Oliver, a noob of web animation,these two days I'm trying to do gsap marquee side project, I build 500 dom boxes as the sandbox url:
https://codesandbox.io/s/gsap-marquee-test-6zx2d?file=/src/App.js&fbclid=IwAR1tbmloHRXHUBHKG5FjBGDAx0TFd9sTkBJfSwpye8CQteO-TO8FNi1w4mw
and I have few question:
1.I used setTimeout to seperate each box as a unique timeline animation,so that the single box animation could go to another line immediately after finished last line, instead of waiting the other 499 boxs finished in the same line if I use property stagger.
This method would produce 500 timeline instances,it seems not a good idea, are there any methods could produce the same animation in one or few timeline?
2.If I do such animation in canvas,the browser render effciency would be better?
You should avoid using setTimeout with GSAP as it's best to use GSAP to control the timing of things.
In this situation, you can probably make use of GSAP's staggers. You should also learn about the position parameter of GSAP's timelines. If you use one (or both, depending on the exact effect that you need) of these you should be able to avoid creating so many timelines.
Additionally, your animation is not responsive. You probably want to make use of functional properties (where your properties of a tween are functions, not just hard numbers) with timeline invalidation to make it responsive.
I also highly recommend going through the most common GSAP mistakes article as you're making some of them.
As for using canvas for rendering your boxes, it probably depends on what your boxes are like. In most cases it'd probably be faster to use canvas, yes. But the slow part of animating these boxes is not anything related to the animation functionality itself, per se. It's related to render speed. In general it's faster to render a bunch of objects to canvas than it is to render a bunch of DOM elements.
Video of what's happening exactly
Specs are:
Display being recorded 2560x1080#60hz
Display that the window goes offscreen 3840x2160#24hz (tested with 60hz too)
Windows 10
GPU Nvidia 970 GTX
Just started learning godot this week and lost hours to this strange behavior.
Godot specifics:
Scale of shapes and bodies are not modified (not to mess with physics)
Starting out trying to create an Entity class, that extends KinematicBody2D, to create instances of enemies within my game. Just using the dummy block for now to test if collisions are indeed working (stopped here due to what happened on the video)
The big dummy square that has one square texture is said Entity, with a collision with huge Y size just to test things out.
The area2d I want to trigger the signal is the small rectangle in front of the character.
Is there something I should know that is causing the signal to only fire while the debug window is on the other display? Should I just move the debug window to the other display and trust the game will work?
Code snippets
Creation of Area2D inside my animation controller
func _create_shape_with_collision(s : Shape2D, parentNode : Node) -> Node:
var ret = Area2D.new()
ret.connect('body_entered', self, '_check_body_entered')
var c = CollisionShape2D.new()
c.shape = s
parentNode.add_child(ret)
c.disabled = true
c.name = 'collision_shape'
ret.add_child(c)
return ret
signal function
func _check_body_entered(body : Node):
print(body.name)
PS: Attempted to type some stuff to help with autocomplete within Godot's interface, but my created classes were not working properly.
PS2: posted this same message on godot's reddit page, in hopes of better visibility
Make sure you have a matching Collision layer and mask in the Area2D node.
Shape2D is a resource, meaning if you don't create .new() then all CollisionShape2D are using the same instance of the shape. If anyone sets explicitly it free it's gone for everyone (so try printing if you accidentally are assigning a null shape). There's some weirdness on resizing after assigning not happening when CollisionShape2D is ready.
But also you have c.disabled = true that probably shouldn't be there.
Because #Theraot laid a path towards writing an issue on Godot's Github page, I was able to determine the cause of the above bug, while creating a minimal project.
In fact, it does not relate at all with the code, but on project settings. The physics FPS was set at 60, while my secondary screen was able to capture the event, as VSYNC was also on by default (caps FPS at refresh rate, secondary screen is 24hz).
Increasing the physics FPS to 120 (empyrical at this point) made the signal work on all displays.
Will gladly accept a better answer, explaining what are the impacts of changing such number (the strain on devices etc), if it is a bad practice or if there is another way to configure individual faster ticks for Area2Ds or PhysicsBody2Ds. Could not write such answer due to my current lack of knowledge/research. Trying to write it at this point would be a sophism.
Since i'm just coding some basic game elements while writing a Game Design Document, it's so far so good for me.
Edit:
After an insight from user #Theraot, I overlooked how different _process and _physics_process worked; For my use case, most of what I was doing should be inside _physics_process, so I could revert the engine's physics FPS back to default value.
In the Godot Engine, I am wondering what happens when objects/scenes leave the viewport? For example: I am trying to make a large map with lots of scenes/entities (such as multiple moving enemies, as well as resource nodes). I am trying to figure out the best way to handle the entities that no longer need to be loaded in memory.
My initial thought was that every tile that is moved to, check the "map" array that holds all the tiles and load the new ones off the screen a little, and vice versa for the ones that will disappear. I assume this is horrible practice. I also thought of having "regions" that once entered, could load upcoming sections - but that also gets super complicated.
I noticed that Godot is already handling part of this problem. As an example, when an object emitting particles leaves the viewport, it stops emitting particles.
Globally performancewise, having multiple instances shouldn't be a problem, but if you have a lot of entities, you may want to execute code only when they are in viewport.
For instance :
if(isInViewport):
Do everything
Else:
Do nothing but exist
To that purpose the VisibilityNotifier2D class may be usefull.
Apologies if there is a thread for this already, I couldn't find one that I could get my teeth into.
Anyway, I'm new to WPF and want to create a custom control that will be a sort of graphic control. The graphic will always consist of a circle, containing a matrix of several squares (from several hundred to several thousand actually) The squares need to respond to mouse click and mouse over events (and ideally be possible to navigate/select via keyboard.) Each square will represent an object I've coded.
In the past I've used a grid control to display the coloured squares (with VCL in CBuilder) but I would like to make a graphical version. (Actually, another question I'd like to ask is, is there a WPF grid control where I can set the colours of individual cells?)
The question is, where to start? Do I start with a canvas and draw on it? Do I derive from an existing object? I'm just a little lacking on ideas on implementation so any pointers or advice you can offer will be greatly received.
BBz
First off I would suggest getting a decent handle on WPF and how it approaches the problem set. It is vastly different from previous .NET Desktop technologies such as WinForms. Once you have a decent understanding in regards to the separation of logic from UI and how WPF approaches the problem then you can dive in and begin making the right decisions based upon what you encounter.
The problem you mention can be solved in multiple ways. In regards to your question about making use of a Grid, that could be done as that is a layout type. It is vastly superior to the Canvas in terms of arranging your visual structure. The defined rows/columns are nothing more then containers which can hold varying UI objects. Therefore pushing a Rectangle into the Grid and coloring as desired would give you the effect you are looking for. This Rectangle could then become a custom control which would allow you to define varying properties on, as well as specific triggers for mouse overs, etc...
At a higher level you will want to encapsulate this logic as a UserControl which will also hold your custom control. Perhaps the UserControl contains the Grid which will make use of your custom control.
Hopefully this gives you some ideas around how to get started, however getting a better understanding of WPF will help you immensely in achieving your goal.