2D Shooter Bullet Mechanics

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By LG

Hi
I’m working on a simple 2d shooter game. Ground and walls are created using TileMap. Player is a KinematicBody2D node. The bullets are instances of an Area2D node created upon pressing the left mouse button. Shooting works nicely, however, I have trouble detecting collisions between bullets and tiles of the tilemap. I tried using body_entered() signal combined with queue_free(), which didn’t work. The bullets flew through the wall and continued onto the next one until they flew out of the map. I don’t understand why this isn’t working.

Do you have suggestions or fixes for this problem? Or perhaps a different and better way of modeling bullets ?

Thank you very much for answers

Here is the bullet code

extends Area2D

var SPEED = 1800
var DIRECTION = null 

func _process(delta):
	if DIRECTION != null:
		position += SPEED*DIRECTION*delta 
	
func _on_Bullet_body_entered(body):
	queue_free()

And here is the Player code where bullets are created

extends KinematicBody2D

const GRAVITY = 100
const X_SPEED = 400
const JUMP_FORCE = 1000
const MID_TO_SHOULDER = Vector2(0, -16)

var facing_right = 0
var y_speed = 0

var aim_angle = null 
var gun_start_point = null
var gun_end_point = null 

var Bullet = preload("res://Bullet/Bullet.tscn")

func _physics_process(delta):
	#turns the gun Line2D according to mouse position
	$Line2D.look_at(get_global_mouse_position())
	
	#checks for movement to the sides input 
	facing_right = 0
	if Input.is_action_pressed("move_right"):
		facing_right = 1
	if Input.is_action_pressed("move_left"):
		facing_right = -1
		
	#every frame y_speed is augmented 
	y_speed += GRAVITY
	
	#if player is on floor, y_speed is reset -> constant 
	if is_on_floor():
		y_speed = GRAVITY
	#jump 
	if is_on_floor() and Input.is_action_pressed("jump"):
		y_speed = -JUMP_FORCE
	
	move_and_slide(Vector2(facing_right*X_SPEED, y_speed), Vector2(0, -1))
	
	#creates instance of Bullet, sets its starting position and direction 
	if Input.is_action_just_pressed("fire"):
		var b0 = Bullet.instance()
		b0.position = position + MID_TO_SHOULDER
		b0.DIRECTION = (get_global_mouse_position() - (position + MID_TO_SHOULDER)).normalized()
		get_node("/root/World").add_child(b0)
	




	 
:bust_in_silhouette: Reply From: kidscancode

There are a couple of possibilities:

  1. Does it work if you slow your bullets down?

If so, then you’re experiencing “tunneling”. The per-frame movement distance of the bullet is large relative to the width of the wall. Possible solutions: slower bullets, thicker walls, raycasting.

  1. If it doesn’t work with slower bullets, then the bullet area isn’t detecting the collision body.

First try turning on “Visible Collision Shapes” in the Debug menu. Make sure the shape of the bullet and the wall are actually overlapping.

Second, did you set up collision layers? Check that the bullet’s collision mask matches the tilemap’s layer.

Yup it had to do with the bullets being too fast…thanks for the response

LG | 2020-04-14 14:44