Why isn't my code working for basic Movement in Godot? - 2d

I just started a new project in godot. So far I have one png which is the main player. I have added a sprite and CollisionShape2D to the player. When i run the game the player does not move (using keys). Does anyone know what is going on here? Heres my code:
extends KinematicBody2D
export var speed = 10.0
export var tileSize = 32.0
var initpos = Vector2()
var dir = Vector2()
var facing = 'down'
var counter = 0.0
var moving = false
func _ready():
initpos = position
func _process(delta):
if not moving:
set_dir()
elif dir != Vector2():
move(delta)
else:
moving = false
func set_dir(): #set moving
dir = get_dir()
if dir.x != 0 or dir.y != 0:
moving = true
initpos = position
func get_dir(): #user input
var x = 0
var y = 0
if dir.y == 0:
x = int(Input.is_action_pressed("ui_right")) - int(Input.is_action_pressed("ui_left"))
if dir.x == 0:
y = int(Input.is_action_pressed("ui_down")) - int(Input.is_action_pressed("ui_up"))
return Vector2(x, y)
func move(delta): #move player linearly
counter += delta + speed
if counter >= 1.0:
position = initpos + dir * tileSize
counter = 0.0
moving = false
else:
position = initpos + dir * tileSize * counter
EDIT:
I have also tried copying and pasting the code directly from Godots documentation and the player still does not move:
extends KinematicBody2D
export (int) var speed = 200
var velocity = Vector2()
func get_input():
velocity = Vector2()
if Input.is_action_pressed('right'):
velocity.x += 1
if Input.is_action_pressed('left'):
velocity.x -= 1
if Input.is_action_pressed('down'):
velocity.y += 1
if Input.is_action_pressed('up'):
velocity.y -= 1
velocity = velocity.normalized() * speed
func _physics_process(delta):
get_input()
velocity = move_and_slide(velocity)

I figured it out. When adding a new script I did not add it to the Player but to the scene.

Related

KinematicBody2D moves only to left and right

So i'm a complete newbie to coding and so i followed this tutorial:
https://www.youtube.com/watch?v=BeSJgUTLmk0
And the i cant move KinematicBody2D up nor down
Here's the code
extends KinematicBody2D
var MaxSpeed = 500
var Accel = 5000
var Motion = Vector2.ZERO
func _physics_process(delta):
var Axis = GetInputAxis()
if Axis == Vector2.ZERO:
ApplyFriction(Accel * delta)
else:
ApplyMovement(Axis * Accel * delta)
Motion = move_and_slide(Motion)
func GetInputAxis():
var Axis = Vector2.ZERO
Axis.x = Input.get_action_strength("ui_right") - Input.get_action_strength("ui_left")
Axis.y - Input.get_action_strength("ui_up") - Input.get_action_strength("ui_down")
return Axis.normalized()
func ApplyFriction(amount):
if Motion.length() > amount:
Motion -= Motion.normalized() * amount
else:
Motion = Vector2.ZERO
func ApplyMovement(acceleration):
Motion += acceleration
Motion = Motion.clamped(MaxSpeed)
and yes my keybinds are set properly

Move and rotate object around pivot and resume from where it stopped

I'd like to move an object around another - just as if the one object was a child of the other. This is GDscript - Godot Engine 3.2, but the logic should be very similar to other game engines.
Whenever I hold spacebar the green cube follows the blue cubes rotation.
First GIF demonstrates the green cube starting at position Vector3(0, 4, 0) without any rotation applied. This works perfectly fine.
In the second GIF I'm holding and releasing spacebar repeatedly. I would expect the green cube to continue from where it left, but instead it "jumps" to a new position and continues from there.
Code below does not include the actual rotation of the blue cube (pivot point), but only the calculations needed to move/rotate the green cube. Rotation of the blue cube is not an issue. Also, rotation is just for the sake of demonstration - in real scenario the blue cube would be moving around as well.
Rotations are calculated using quaternion, but this is not a requirement.
extends Node
var _parent
var _child
var _subject
var _positionOffset: Vector3
var _rotationOffset: Quat
func _ready():
_parent = get_parent()
_child = $"/root/Main/Child"
func _input(event):
if event is InputEventKey:
if event.scancode == KEY_SPACE:
if event.is_action_pressed("ui_accept") and _child != null:
_subject = _child
_set_subject_offset(_parent.transform, _child.transform)
elif event.is_action_released("ui_accept"):
_subject = null
func _set_subject_offset(pivot: Transform, subject: Transform):
_positionOffset = (pivot.origin - subject.origin)
_rotationOffset = pivot.basis.get_rotation_quat().inverse() * subject.basis.get_rotation_quat()
func _rotate_around_pivot(subject_position: Vector3, pivot: Vector3, subject_rotation: Quat):
return pivot + (subject_rotation * (subject_position - pivot))
func _physics_process(_delta):
if _subject == null: return
var target_position = _parent.transform.origin - _positionOffset
var target_rotation = _parent.transform.basis.get_rotation_quat() * _rotationOffset
_subject.transform.origin = _rotate_around_pivot(target_position, _parent.transform.origin, target_rotation)
_subject.set_rotation(target_rotation.get_euler())
I feel like I'm missing something obvious.
You can easily achieve this by temporarily parenting the subject to the pivot point while preserving the global transform:
extends Spatial
onready var obj1: Spatial = $Object1
onready var obj2: Spatial = $Object2
func reparent(obj: Spatial, new_parent: Spatial):
# Preserve the global transform while reparenting
var old_trans := obj.global_transform
obj.get_parent().remove_child(obj)
new_parent.add_child(obj)
obj.global_transform = old_trans
func _physics_process(delta: float):
obj1.rotate_z(delta)
func _input(event: InputEvent):
if event.is_action_pressed("ui_accept"):
reparent(obj2, obj1)
elif event.is_action_released("ui_accept"):
reparent(obj2, self)
If reparenting isn't feasible, you could instead parent a RemoteTransform to the pivot, and have that push its transform to the object you want to rotate:
extends Spatial
onready var remote_trans: RemoteTransform = $RemoteTransform
func _process(delta):
rotate_z(delta)
func attach(n: Node):
# move the remote so the target maintains its transform
remote_trans.global_transform = n.global_transform
remote_trans.remote_path = n.get_path()
func detach():
remote_trans.remote_path = ""
repost, Thank You path9263, answered Jun 4, 2019 by path9263 (134 points)
func rotate_around(obj:Spatial, point:Vector3, axis:Vector3, phi:float):
# https://godotengine.org/qa/45609/how-do-you-rotate-spatial-node-around-axis-given-point-space?show=45970#a45970
obj.global_translate(-point)
obj.transform = obj.transform.rotated(axis, phi)
obj.global_translate(point)
the below functions do not work
func rotate_around_point(transform_me:Spatial, pivot_point:Vector3, axis:Vector3, phi:float):
# #4: busted, no rotation
# https://stackoverflow.com/a/59939086/1695680
# Preserve the global transform while reparenting
var pivot_spatial = Spatial.new()
pivot_spatial.translation = pivot_point
var parent_orig = transform_me.get_parent()
var transform_orig = transform_me.global_transform
parent_orig.remove_child(transform_me)
pivot_spatial.add_child(transform_me)
transform_me.global_transform = transform_orig
pivot_spatial.rotate(axis, phi)
var transform_rotated = transform_me.global_transform
pivot_spatial.remove_child(transform_me)
parent_orig.add_child(transform_me)
transform_me.global_transform = transform_orig
func rotate_around_point(transform_me:Spatial, pivot_point:Vector3, axis:Vector3, phi:float):
# busted, no rotate
# https://stackoverflow.com/a/59939086/1695680
var remote_trans : RemoteTransform = RemoteTransform.new()
remote_trans.global_transform = transform_me.global_transform
remote_trans.remote_path = transform_me.get_path()
remote_trans.rotate(axis, phi)
remote_trans.remote_path = ""
func rotate_around_point(transform_me:Spatial, pivot_point:Vector3, axis:Vector3, phi:float):
# busted, local rotate
# https://godotforums.org/discussion/comment/43335/#Comment_43335
var gto_orig = transform_me.global_transform.origin
transform_me.global_transform.origin = pivot_point
transform_me.rotate(axis, phi)
transform_me.global_transform.origin = gto_orig
func rotate_around_point(transform_me:Spatial, pivot_point:Vector3, axis:Vector3, phi:float):
# busted, no rotate
# https://godotengine.org/qa/34248/rotate-around-a-fixed-point-in-3d-space?show=38928#a38928
var start_position : Vector3 = transform_me.translation
var pivot_radius : Vector3 = start_position - pivot_point
var pivot_transform : Transform = Transform(transform.basis, pivot_point)
var transform = pivot_transform.rotated(axis, phi).translated(pivot_radius)
transform.xform(transform_me)

Geometry in Plan (Math)

My problem is to know whether or not a point is contained in a polygon (sets of points) on the same surface.
Simple example in my favorite language DART
Point myPoint = new Point(10, 12);
List<Point> myPolygon = [ // The Polygon, for example is simple rect
new Point(2, 7),
new Point(15,7),
new Point(15, 18),
new Point(2, 18)
];
bool pointIsContainedInPolygon(List Polygon){
// .. data processing ...
}
I need to know what is the function: pointIsContainedInPolygon(myPolygon)
I have resumed the code data in the How can I determine whether a 2D Point is within a Polygon? post in dart, here is the result (tested)
bool pnpoly(Point point, List<Point> polygon){
// Step 1: Cut and detail
int nvert = polygon.length;
List<int> vertx = [];
List<int> verty = [];
for(Point vert in polygon){ // Listing x and y pos of all vertices
vertx.add(vert.x);
verty.add(vert.y);
}
// Step 2: Calcul..
bool c = false;
int j = nvert-1;
for (int i = 0; i < nvert; j = i++){
if( ((verty[i]>point.y) != (verty[j]>point.y)) && (point.x < (vertx[j]-vertx[i]) * (point.y-verty[i]) / (verty[j]-verty[i]) + vertx[i]) ){
c = !c;
}
}
return c;
}
Here is my test
List<Point> myPolygon = [ // classic rectangle
new Point(2,2),
new Point(52,2),
new Point(52,41),
new Point(2,41)
];
Point myPoint = new Point(53,40);
print( pnpoly(myPoint, myPolygon) ); // false

Qt Quick MapPolyLine insertCoordinate

I have a PolyLine on my map and want to add a new co-ordinate to it when a user clicks between two existing points.
I can get the click event with:-
MouseArea {
id: mouseArea
anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton
onClicked: {
console.log('LINE');
}
}
But I cannot figure out how to work out the required index for insertCoordinate() as there does not appear to be a method to get the start/end vertices of the segment clicked. Is this possible?
I had a similar problem. Currently it cannot be done without writing a new Map object type. So I've changed approach completely and done the following:-
stopped using QtLocation for the map as it is too restrictive at present
integrated a WebKit control with Leaflet as the map provider in the browser HTML
used WebChannel and the WebSocketServer to communicate with the map via the javascript API
This has given me all the flexibility I need on the map as Leaflet is easy to configure and extend whilst allowing me to write the rest of the desktop app in Qt
I've revisited this project and found a way to do it without using Webkit. It is quite involved:-
1) use the click to get a coordinate
var mapCoord = gpxLine.mapToItem(mapView,mouseX,mouseY);
var coord = mapView.toCoordinate(Qt.point(mapCoord.x,mapCoord.y));
2) use this coordinate to iterate through the path and calculate the path line segment that it is closest to
float distance = 1000000;
float dx = 0;
int index = 0;
float x0 = coordinate.longitude(),
y0 = coordinate.latitude(),
x1y1x,
x1y1y,
x2y2x,
x2y2y;
double A,B,C,D,dot,len_sq,param,xx,yy,d_x,d_y;
for(int i = 0; i < trackpoints.count() - 1; i++){
//Distance from line algorithm https://stackoverflow.com/questions/849211/shortest-distance-between-a-point-and-a-line-segment
x1y1x = trackpoints[i].latlon.longitude();
x1y1y = trackpoints[i].latlon.latitude();
x2y2x = trackpoints[i+1].latlon.longitude();
x2y2y = trackpoints[i+1].latlon.latitude();
A = x0 - x1y1x;
B = y0 - x1y1y;
C = x2y2x - x1y1x;
D = x2y2y - x1y1y;
dot = A * C + B * D;
len_sq = C * C + D * D;
param = dot /len_sq;
if(param < 0 || (x1y1x == x2y2x && x1y1y == x2y2y)){
xx = x1y1x;
yy = x1y1y;
} else if ( param > 1 ){
xx = x2y2x;
yy = x2y2y;
} else {
xx = x1y1x +param * C;
yy = x1y1y + param * D;
}
d_x = x0 - xx;
d_y = y0 - yy;
dx = sqrt(d_x * d_x + d_y * d_y);
if(dx < distance){
distance = dx;
index = i;
}
}
3) this gives me the index so I can now insert the coordinate at this index

Paper.js animating : Movement according to a paths normal

I am trying to animate a line and its normal ( another line ). But when i change position after or before setting rotation of the normal strange animation occurs.
Is there anybody who has an idea on that?
I have this code in sketchpad:
http://sketch.paperjs.org/#S/jVJLb5tAEP4rKy7BqgvUbS+OcogstT2klaUeeohzIDA2q+AZtAyOI8v/vbM7mFDLUcqJne8xz0OE+RaiefT7CbioomlUUOnfu9wZ6hjcD3NjZll2vcIh9EdCn4fQxlHXSATh2Xz3//GkR9rGIvTIMucqPuzn2dS8zLOjp6x4xYGS5GU5YJo0/XKZ8lELeCWe0Vp29AQLqslJ4isH5VWPa0m4HNcTtIjLc9lj3YHXCeLzBj5Z5FgqzCaTC8BXRYJfmgrc2B2xz7VMHqnDsk2YmjtYc6BoQWFy3mhR2bp0gPF96GIqqgfvpYSGWsuWUNxkArIL373M/6hWqJ3VVAhBp7ABvqMi96Jbjj/NstNGkNw2r8e8XyHyyuoHMsopxvKUJnUgjjhniNUpyXFTg+p2Fp4Twm9ODkpk6w4L7xDDDpAn5rBCM/r6GXC4E4tdK5KfspNEHipJ2IrRab3KLOgfrjwvc9PULCqpDQxXYPZmaIfWIdLCZisyc+pLVf0JKdbezx607+TFfLgZUr/L3nv2GXfcw7uLGo/pP5c2JDnp3l7h2D1c6lsLFcdjdPwL
var outerH = 200;
var outerW = 300;
var group = new Group();
var spine = new Path({x:0, y:0});
spine.add({x:0, y:outerH/4});
spine.add({x:-outerW, y:outerH});
spine.strokeColor = 'red';
var nP = new Path();
nP.strokeColor = 'blue';
nP.add(new Point(0, 0))
nP.add(new Point(50, 0));
//nP.pivot = nP.bounds.topLeft;
group.addChildren([spine, nP]);
group.position = {x:200, y:300};
var loc = spine.getLocationAt(120);
var normal = spine.getNormalAt(120);
nP.position = loc.point;
nP.rotate(normal.angle);
view.onFrame = function(event) {
var sinus = Math.sin(event.time );
var cosinus = Math.cos(event.time );
// Change the x position of the segment point;
spine.segments[2].point.y += cosinus ;
spine.segments[2].point.x += sinus ;
var loc = spine.getLocationAt(120);
var normal = spine.getNormalAt(120);
nP.position = loc.point;
//nP.rotate(normal.angle);
}
If I uncomment -> nP.rotate(normal.angle); nP is not rotating with the line normal point?
Please read the following post on the mailing list that explains this behavior and offers an option to switch paper.js into a mode that simplifies this scenario:
https://groups.google.com/forum/#!searchin/paperjs/applymatrix/paperjs/4EIRSGzcaUI/seKoNT-PSpwJ
The problem is that in paper.js when you rotate an item and move it, the new rotation is accepted as 0 degree. So I am keeping an oldAngle variable outside the onFrame event. Than do the necessary math in onFrame to calculate the right rotation...
The right code:
var group = new Group();
var spine = new Path({x:0, y:0});
spine.add({x:0, y:50});
spine.add({x:-300, y:200});
spine.strokeColor = 'red';
var nP = new Path();
nP.strokeColor = 'blue';
nP.add(new Point(0, 0))
nP.add(new Point(50, 0));
group.addChildren([spine, nP]);
group.position = {x:200, y:300};
var loc = spine.getLocationAt(120);
var normal = spine.getNormalAt(120);
nP.position = loc.point;
nP.rotation = normal.angle;
var oldAngle = normal.angle; // keep the old rotation angle in this variable
view.onFrame = function(event) {
var sinus = Math.sin(event.time );
spine.segments[2].point.y += sinus ;
spine.segments[2].point.x += sinus ;
var loc = spine.getLocationAt(120);
var normal = spine.getNormalAt(120);
nP.position = loc.point;
nP.rotation += normal.angle - oldAngle; // here we do the necessary math
oldAngle = normal.angle;
}

Resources