So I'm trying to program a game using flash, and it's my very first time and I can't get something to work.
In the game, a ball will float across the screen and if you click on it you get 2 points. Except when I test it, the first time I click on the ball I get the letters 'eoceeeo' and if I click the ball again I get the letters 'eeoS'. The dynamic text is on a layer with the first frame having the AS of
var _root.score = 0;
gameScore.text = _root.score;
The dynamic text has a varible of _root.score and a name of gameScore
The floating ball has the AS of
on(release) { _root.score+=2; _root.gameScore.text = _root.score; }
If you click on your gameScore dynamic text field, you can scroll down to its Variable property and set that as _root.score. That way, you do not have to call gameScore.text = _root.score every time the score changes - it will simply update automatically.
Also, if you remove the var from in front of _root.score = 0, it will be easier for ActionScript to handle. Perhaps, you are casting the score variable as an integer, and the dynamic text field is having trouble displaying it as a string of characters. This can also be solved with String(_root.score) and score.toString().
That should make your code a bit less complex, and help for you to identity your random letters problem, which can't be solved specifically with the information you have here. Hope that helps!
Related
I am completely new to AE expressions.
Suppose that I have bunch of layer markers on a text layer, and the text is linked to a slider control:
Now, what I want is that whenever the playhead (or the current frame) lands on the next marker(s), I want the slider to increment by 1, like this:
I want an expression which I can add to the Slider to achieve the desired result. Your help would be greatly appreciated. Thank you.
I posted this question on Reddit as well, they told me to use ChatGPT. I tried using it, but it doesn't achieve the desired result after trying several different prompts and even when breaking down the problem into parts.
I finally figured it out, I got rid of the slider, added a "Numbers" effect to the text layer (which displays the counter), and added the following expression code to the "Value/..." property:
for (i = 1; i <= thisLayer.marker.numKeys; i++) {
if (thisLayer.marker.key(i).time <= time) {
value = value + 1;
}
else {
value;
}
}
I've followed "Procedural Generation in Godot: Dungeon Generation" by KidsCanCode #https://www.youtube.com/watch?v=o3fwlk1NI-w and find myself unable to debug the current problem.
This specific commit has the code, but I'll try to explain in more detail bellow.
My main scene has a Camera2D node, a generic Node2D calles Rooms and a TileMap, everything is empty.
When the script starts, it runs a
func make_room(_pos, _size):
position = _pos
size = _size
var s = RectangleShape2D.new()
s.custom_solver_bias = 0.5
s.extents = size
$CollisionShape2D.shape = s
A few times and it fills $Rooms using .add_child(r) where r is a instance of the node that has the make_room() function. It will then iterate over $Rooms.get_children() a few times to create a AStar node to link all the rooms:
The magic comes when make_map() is called after afterwards, it fills the map with non-walkable blocks and then it carves the empty spaces, which works fine too:
There is a find_start_room() that is called to find the initial room, it also sets a global variable to the Main script start_room, which is used to write 'Start' on the map using draw_string(font, start_room.position - Vector2(125,0),"start",Color(3,4,8))
When I hit 'esc' it runs this simple code to instance the player:
player = Player.instance()
add_child(player)
player.position = start_room.position + Vector2(start_room.size.x/2, start_room.size.y/2)
play_mode = true
The problem comes when spawning the player. I tried doing some 'blind' fixing, such as adding or subtracting a Vector2(start_room.size.x/2, start_room.size.y/2) to player.position to see if I could make it fall within the room, to no avail.
Turning to the debugger didn't help, as the positions expressed by the variable inspectors don't seem to mean anything.
I tried implementing a simple 'mouse click print location':
print("Mouse Click/Unclick at: ", event.position)
print("Node thing",get_node("/root/Main/TileMap").world_to_map(event.position))
And also a 'start_room' print location:
print(get_node("/root/Main/TileMap").world_to_map(start_room.position))
And a when player moves print location, written directly into the Character script:
print(get_node("/root/Main/TileMap").world_to_map(self.position))
Getting results like the ones bellow:
Mouse Click/Unclick at: (518, 293)
Node thing(16, 9)
(-142, 0)
(-147, -3)
So, the player doesn't spawn on the same position as the start_room and the mouse position information is not the same as anything else.
Why is the player now spawning correctly? How can I debug this situation?
EDIT1: User Theraot mentioned about how the RigidBody2D is doing some weird collisions, and from what I understood, changing their collision behavior should fix the whole thing.
There's a section on the code that -after generating the random rooms- it removes some of the rooms like this:
for room in $Rooms.get_children():
if randf() < cull:
room.queue_free()
else:
room.mode = RigidBody2D.MODE_STATIC
room_positions.append(Vector3(room.position.x, room.position.y, 0))
From what I understand, if the room is randomly selected it will be deleted using queue_free() OR it will be appended to a room_positions for further processing. This means if I shift all the rooms to a different collision layer, the player/character instance would be alone with the TileMap on the same collision layer.
So I just added a simple room.collision_layer = 3 changing this section of the code to
for room in $Rooms.get_children():
if randf() < cull:
room.queue_free()
else:
room.mode = RigidBody2D.MODE_STATIC
room.collision_layer = 3
room_positions.append(Vector3(room.position.x, room.position.y, 0))
It doesn't seem to have changed anything, the player still spawns outside the room.
Do you see the rooms spread outwards?
You didn't write code to move the rooms. Sure, the code gives them a random position. But even if you set their position to Vector2.ZERO they move outwards, avoiding overlaps.
Why? Because these rooms are RigidBody2D, and they do push other physics objects. Such as other rooms or the player character.
That's the problem: These rooms are RigidBody2D, and you put your KinematicBody2D player character on top of one of them. The RigidBody2D pushes it out.
The tutorial you followed is exploiting this behavior of RigidBody2Ds to spread the rooms. However you don't need these RigidBody2D after you are done populating your TileMap.
Instead, you can store the start position in a variable for later placing the player character (you don't need offsets - by the way - the position of the room is the center of the room), and then remove the RigidBody2Ds. If you want to keep the code that writes the text, you would also have to modify it, so it does not fail when the room no longer exists.
Alternatively, you can edit their collision layer and mask so they don't collide with the player character (or anything for that matter, but why would you want these RigidBody2Ds that collide with nothing?).
Addendum post edit: Collision layers and mask don't work as you expect.
First of all, the collision layer and mask are flags. The values of the layers are powers of two (1, 2, 4, 8...). So, when you set it to 3, it is the layer 1 plus the layer 2. So it still collides with a collision mask of 1.
And second, even if you changed the collision layer of the rooms to 2 (so it does not match the collision mask of 1 that the player character has). The player character still has a layer 1 which match the collision mask of the rooms.
See also the proposal Make physics layers and masks logic simple and consistent.
Thus, you would need to change the layer and mask. Both. in such way that they don't collide. For example, you can set layer and mask to 0 (which disable all collisions). The algorithm that populates the TileMap does not use the layer and mask.
This is a bit of a long-shot. I really don't know where to ask this question.
I've been trying out CodeConnection + MakeCode with Minecraft and I haven't been able to figure out if there is correct way to place half-slabs at 0.5 step y axes increments.
I tried using a line between 2 points, but it left gaps between each slab.
If I try moving up 0.5, then it rounds it up to 1, and again leaves gaps.
It appears that all of the builder functions seem operate at a resolution of 1 block. However in-game I can obviously place slabs in 0.5 block increments to make stairs etc.
Blocks only exist at integer coordinates. Half slabs that exist in the top half of their space are still at a full integer coordinate. They just have a BlockState value of bottom=top (or top_slot_bit=true on Bedrock, represented by the integer value 8 as a bitflag, eg: 0b1... where the . bits are the integer representation of what type of slab (wood, stone, quartz...)).
What you're looking for is this widget, under Blocks:
You can set the block and then an integer representation of the desired data value (see the wiki on data values) in the numerical slot. This widget can then be dragged into the (block) portion of any block widget:
You'll probably have to some variable fiddling to get the data value to swap back and forth as you need it to, but that should solve the hurdle you've been facing.
I'm trying to create a Minesweeper game.
I have a 4x4 set of buttons equally spaced in main.Storyboard.
My plan is to create a random array which places a 0 or * in the 1st/2nd/3rd/4th arrays. I would do this by using the arc4Random method.
With the remaining blank cells, I then have to check how many mines there could be for the 8 (potential) squares around the cell/button. This would be governed by the boundary conditions (0,0 to 3,3).
Once this is set up, I would then set the background and number label to the same colour. I could then write an if or else statement to change the colour after each button is pressed.
I'm quite struggling how to start this off and actually write this. Can anyone please give me some advice please?
Well,
you can get a boolean like this.
bool hasMine = arc4random() % 2;
this will give you 50% chance to get a bomb... if you want less bomb, increase the value (3 will give you 2 bomb free square, for one with a bomb, etc..)
then a "" or a "*" like this;
NSSString * value = hasMine ? #"*" : #"" ;
then it's just a matter of a for loop to populate your arrays.
for the sake of performance, I wouldn't use a n x n nested array but a single arrray of nxn size (in your case a array with 16 value). Then I will set a tag for 0 to (nxn -1) to each button based on its position, and on click I'll get the tag of the pressed button and retrive the value of the object at this position in the array
Many times when i am programing a UI , i have to put some view after the previous view, so to get the previous value i am calculating its x/y position ,add to this its width/height, and get the desired frame to the next view ,
newX=previous.frame.origin.x+previous.frame.size.width;
newy=previous.frame.origin.y+previous.frame.size.height;
Is there a short way to get that value of a view ,in one word ?
When you have to do that many times , it becomes a real headache every time again .
You can use C functions declared in CoreGraphic.h:
newX = CGRectGetMaxX(previous.frame);
newy = CGRectGetMaxY(previous.frame);
You can define a macro
#define NextX(frame) (frame.origin.x+frame.size.width)
#define NextY(frame) (frame.origin.y+frame.size.height)
and then you can use it like
newX=NextX(previous.frame);
newY=NextY(previous.frame);