2D movement how to fix? [duplicate] - game-engine

This question already has answers here:
KinematicBody2D not moving in Godot
(2 answers)
Closed 1 year ago.
I asked this question before and got a answer but that answer didnt work nor did the guy respond so here is my last effort, The kinematic body isnt moving yes i added controls to the project setting, yes there are no errors. I dont know what to do. `
Extends KinematicBody2D
var movespeed = 500
func _ready():
pass # Replace with function body.
func _physics_process(delta):
var motion = Vector2()
if Input.is_action_pressed("up"):
motion.y -= 1
if Input.is_action_pressed("down"):
motion.y += 1
if Input.is_action_pressed("left"):
motion.x += 1
if Input.is_action_pressed("right"):
motion.x -= 1
motion = motion.normalized()
``

You've created a Vector called motion and set it's values, however you never actually do anything with that data.
It's best to use something like move and slide to alter the position of a kinematic body.
However, using what you have, you can add your motion values to the global_transform of the node which would have a similar effect.

Related

Detect collision between two 2D kinematics bodies godot

I'm doing a very simple 2D platform game project, you can see here how it is so far: https://master.d3kjckivyd1c76.amplifyapp.com/src/Games/PlatformGame2D101/index.html
But I can't detect the collision between the enemy (the chainsaw) and the player.
I have this code to detect if the two bodies are colliding, but it only prints the Enemy when the player is moving:
func _physics_process(delta: float) -> void:
velocity = move_and_slide(velocity, Vector2.UP)
for i in get_slide_count():
var collision = get_slide_collision(i)
if collision.collider.is_in_group("Enemy"): print("Enemy")
original file
I uploaded the project to the Bitbucket
Thanks any help : )
I did plenty of 2d games using pygame and i used this two.
You can use sprite.spritecollideany() which takes 2 arguments. The sprite u want to collide, in your case the chainsaw with another group of sprites. this requires a loop, which will look like this:
for swordman in swordsmen1_army:
# Swordsman1 attackin Swordsman2
colliding_sword2 = pygame.sprite.spritecollideany(swordman, swordsmen2_army)
if colliding_sword2:
swordman.attacking = True
swordman.unleash = False
if swordman.index == 3:
colliding_sword2.health -= SWORD_HIT
If you want to collide just two sprites you can use pygame.Rect.colliderect() which checks for detection of 2 sprites with each other. This one requires no loop and looks like this:
if pygame.Rect.colliderect(ball.rect, border1.rect):
ball.down_collision = True
ball_y_speed *= -1
Both of them will return a boolean value and from there, you can use an if statement and continue with the code.
The answer: https://www.reddit.com/r/godot/comments/yojmz8/detect_collision_between_two_2d_kinematics_bodies/
But basically the player, it’s not moving, so it's not colliding 🤦
Here it's the changes that I made to fix: https://bitbucket.org/201flaviosilva-labs/platform-game-2d-101-godot/commits/61e37823eb9758fdafd222f2cdecf3e0668a3808

How to fix: code not running on certain frames

I have been trying to make my character shoot a projectile on a particular frame of animation. However, sometimes it works and other times it just ignores creating the projectile.
I've tried using alarms instead of checking for the image index but I can't get the timer low enough to get the perfect timing.
I think it may be a problem with the image speed being 0.2 instead of 1.
I'm using a state machine to make it switch between moving and shooting, but I checked and it isn't a problem with state switching over as it changes when I want it to.
Here is relevant code from the shooting state:
if image_index == 2 {
instance_create(x+20*image_xscale,y,obj_projectile);
}
Here is the code that changes the tank over to the shooting state from the main state:
if key_shoot{
state = states.shoot;
image_speed = 0.2;
sprite_index = spr_tankShoot;
}
There is also an animation end event in the object with the following code:
if sprite_index == spr_tankShoot{
state = states.normal;
}
If anyone can see something wrong with the code and/or know what might be going wrong with this, it'd be much appreciated.
I think it may be a problem with the image speed being 0.2 instead of 1.
This is possible - if your animations have different speeds and you don't tend to reset image_index on animation start, you may end up with varying starting indexes (suppose, 0.1) that would not fall right on 2.0 when adding 0.2 to them. Checking that a frame is precisely a number is a not-as-good practice in general though.
You could store image_index at the end of the frame for future reference,
image_index_previous = image_index;
and then check that image_index stepped over 2 since the last frame:
if image_index_previous < 2 && image_index >= 2 {
instance_create(x+20*image_xscale,y,obj_projectile);
}

Box2D collision detection fails after firing a lot of bullets

I am working on a physics game and encountered a strange bug: sometimes, after firing a lot of bullets, collision detection starts to fail.
As can be seen in the following GIF, the collision works only on half the platform, which is very strange. Also, the Box2D debug renderer is enabled and it can also be seen that the platform is a single body.
Here is how I get this bug to happen, as it only happens only after firing lots of bullets (in the beginning everything works fine):
Notes:
- the bullet has the bullet field set to true
- I set the player's bullet field to true, did not make a difference
- the player is 1 meter by 1 meter
- the player and the bullets are DynamicBodies and the platforms are StaticBodies
- the map is near to (0, 0), though it goes a bit in the negatives (-1.5), I doubt it matters
- the categoryBits and maskBits are correct (the collision should happen, and it does happen, but glitches)
- after the bullets disappear, the number of bodies is the same as when the game starts (so they are actually destroyed)
- the World's gravity is (0, -25f)
- the game runs at 60fps
Here is the Box2D timestep code, similar to the stepping code from the libGDX wiki:
companion object {
private const val TIME_STEP = 1f / 300f
private const val VELOCITY_ITERATIONS = 6
private const val POSITION_ITERATIONS = 2
}
private var accumulator = 0f
override fun update(deltaTime: Float) {
accumulator += Math.min(deltaTime, 0.25f)
while (accumulator >= TIME_STEP) {
world.step(TIME_STEP, VELOCITY_ITERATIONS, POSITION_ITERATIONS)
accumulator -= TIME_STEP
}
}
I tried changing:
- TIME_STEP to a lower value, like 1/60f
- VELOCITY_ITERATIONS a bit higher, to 8
- POSITION_ITERATIONS a bit higher, to 6
- VELOCITY_ITERATIONS and POSITION_ITERATIONS to 100
and there was no (obvious) difference.
Concern:
The bugged platform seems to start behaving like a bullet (it doesn't collide with other bullets or with the player), at least halfway. So could its categoryBits and maskBits be changed on-the-fly, after a lot of world.createBody() and world.destroyBody(), maybe due to pooling?
So what should I try for the collision not to fail in this case?
I finally managed to fix it.
The solution I found was to loop through every entity that has a body and call refilter(), which seems to fix it:
engine.getEntitiesFor(Family.one(BodyComponent::class.java).get()).forEach {
it.body.body.fixtureList.first().refilter()
}
In the future, I could call refilter() only when needed (if I can determine when I have to call it) instead of calling it every frame, but it works for now.
It looks like you should call refilter() after you change the filterData of a body (changing its categoryBits or maskBits) outside the FixtureDef, but I don't seem to be doing that (or maybe I am missing something), so it is a bit weird.

Making object move to a touch position - Corona SDK

I'm trying to get a game object to move to a touch location. I've tried numerous different ways of doing it, but all to no avail. I'm updating the objects y position every frame to keep it moving constantly forward, and I'm not sure if this is affecting adding a force or not.
Here is where I move the crow (inside an update function):
crow:translate((platformSpeed),0)
And here is where I'm trying to get the crow to move to the touch position:
local function attack(xPos,yPos)
--get magnitude of touch vector
local magnitude = math.sqrt(xPos*2 + yPos*2)
--normalize vector
xPos = xPos / magnitude
yPos = yPos / magnitude
print(xPos..yPos)
local forceMag = 0.1 -- change this value to apply more or less force
--now apply the force
crow:setLinearVelocity(xPos*forceMag, yPos*forceMag)
--crow:applyLinearImpulse(xPos*forceMag, yPos*forceMag, crow.x, crow.y)
end
local function touchHandler(event)
if (event.phase == "began") then
end
if (event.phase == "ended") then
if (event.yStart>event.y+10) then
jump()
else attack(event.x,event.y) end
end
end
As you can see, I've been trying linear velocity and linear impulse, but the direction is always wrong!
Any help would be great, Thanks!
Alan.
Try this:
local cow = display.newRect(0,0,50,50) -- create your object
local trans
local function moveObject(e)
if(trans)then
transition.cancel(trans)
end
trans = transition.to(cow,{time=200,x=e.x,y=e.y}) -- move to touch position
end
Runtime:addEventListener("tap",moveObject)
Keep Coding.............. :)
This is similar to the recent question.
I have an answer to the recent question, you can check and run my sample code on a blank project to see how it works.
My code uses physics and linear velocity.
https://stackoverflow.com/a/17847475/1605727

Generate a random Y for a sprite

I need some help (duh). I want to generate a random Y position for my game in cocos2d.
So the situation goes like this:
The game spawns a platform every 0.2 second. The iPhone / iPad is in landscape mode. Platform appear on the right of the screen (bigger x than width so that the platform appears outside the screen) and starts moving towards the left end of the screen using CCMoveTo.
I pick a random Y for every platform. The problem is that I do not want to spawn a platform on top of another. This means that I need to make a randY which is not "already taken".
The code I've tried so far is this:
//this is a part of code from my addPlatform function. This part in particular cares for the generation of my Y coordinate.
int randY = arc4random() % (int)(3 * (winSize.height/4)); //This prevents to spawn a Y larger than 3/4 of the screen
//here I would like to loop long enough to find a good Y
while (![self isGoodPlatformY:randY])
{
randY = arc4random() % (int)(3 * (winSize.height/4));
}
The next part is my isGoodPlatformY function
- (bool)isGoodPlatformY:(int)platY
{
CGSize winSize = [[CCDirector sharedDirector] winSize];
int padding = 100;
bool ok = true;
for (CCSprite *body in [self children])
{
if (body.tag > platformBody)
{
if (body.position.x < (winSize.width - padding))
{
if (abs(body.position.y - platY) < 20)
{
ok = false;
}
}
}
}
return ok;
}
I loop through all the bodies with larger tag than my platform. I have different types of platform which I separate by using tag. If the body is a platform I first check the X coordinate. If the platform is enough away (padding) I can spawn a new one at that exact point so I check the next one. If not I want to check the Y of that platform. If the Y coordinate is less than 20 pixels in this case I must find a new Y so thats why set the bool to false and return it after the for loop.
I know there is no need for those curly brackets but I was testing some other stuff, thats why I put them there.
This doesn't seem to work. Hope I made myself clear what I want to accomplish. Any help from your side would be much appreciated. Hope I didn't miss something too newbie style :)
I tagged the question in other languages to because this problem could occur "everywhere".
Assuming that all the spawned platforms have the same tag as you mentioned that you are using tags to separate different types of platforms.
All previous platforms will not return true for this line
if (body.tag > platformBody)
because they all have the same tag, you will compare (1 > 1) which is false.
Therefore your method will always return YES (which is your default value for ok) and will never check to see if the platforms collide with each other.
I recommend stepping through the method to see if this is the case.
Now I have discovered that I can answer my own questions :) (silly me). So yeah, the problem was fixed a long time ago but to anyone who might be reading this, the solution was to change the line:
if (body.position.x < (winSize.width - padding))
To:
if (body.position.x > (winSize.width - padding))