No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Desarrollando la IA de tu oponente

12/17
Recursos

Aportes 16

Preguntas 4

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

o inicia sesi贸n.

Hola, comparto mi soluci贸n 鈥渁ctual鈥 para el funcionamiento del enemigo :)

Esta permite de cierta forma modificar la dificultad, lo realic茅 teniendo en cuenta la distancia de reacci贸n que podr铆a llegar a tener el enemigo respecto a la posici贸n de la pelota, adem谩s esta soluci贸n le otorga al enemigo un poco de movimiento independiente en el eje y, para que parezca que no est谩 todo el tiempo siguiendo la misma direcci贸n de la pelota (al menos cuando no es necesario) y se note un poco m谩s animado.

extends KinematicBody2D

var speed = 600
var direction = Vector2.ZERO
var reaction_dist_x = 0
var reaction_dist_y = 0

onready var ball = get_parent().find_node('Ball')

func _ready():
	randomize()
	
	var window_width = OS.get_window_size().x
	var shape_height = find_node('CollisionShape2D').shape.extents.y
	reaction_dist_x = window_width
	reaction_dist_y = shape_height
	# modify the reaction distance component values in terms of dificulty
	# the difficulty can be graduated through the percentage
	# "more percentage decrease, more difficulty"
	reaction_dist_x -= window_width * 0.35 #easy
	reaction_dist_y -= shape_height * 0.5 #easy
	direction.y = [-1, 1][_random_select()]

func _physics_process(delta):
	var delta_y = ball.position.y - position.y
	
	if ball.position.x > reaction_dist_x && ball.direction.x > 0 && abs(delta_y) > reaction_dist_y:
		direction = Vector2(0, delta_y).normalized()
		move_and_slide(direction * speed)
	else:
		var collide = move_and_collide(direction * speed * delta)
		if collide:
			direction.y *= -1

func _random_select():
	return int(randf() > 0.5)

Si se encuentran con algunas l铆neas confusas o ambiguas, etc鈥 lo siento 馃槗, nunca antes hab铆a visto este lenguaje de programaci贸n, as铆 que por el momento, solo me comprometo a mejorar >:)

Versi贸n del script del oponente para godot 4

extends CharacterBody2D

const SPEED = 600.0
@onready var ball = get_parent().find_child("Ball")

func _physics_process(delta):
	
	velocity.y = _get_oponent_direction() * SPEED
	#velocity.x = 0
	
	move_and_collide(velocity * delta)
	
func _get_oponent_direction():
	
	if abs(ball.position.y - position.y) > 25:
		if ball.position.y > position.y:
			return 1
		else:
			return -1
	else:
		return 0
		

Es importante resaltar que cambi茅 el move_and_slide por move_and_collide porque si la pelota golpea en cierto 谩ngulo al oponente entonces 茅ste hace un slide y se va junto con la pelota.

Yo agregu茅 una l铆nea de c贸digo para que el oponente solo se mueva cuando la pelota este en la mitad del tablero. Esto lo hice para que el oponente no se mueva en todo momento, y solo cuando la pelota este cerca de 茅l

extends KinematicBody2D

var speed = 600
onready var ball = get_parent().find_node("Ball")

func _physics_process(delta):
	if ball.position.x > 960: #esta es la linea que agregu茅
		var direction = Vector2(0, _get_direction())
		move_and_slide(direction * speed)
	
func _get_direction():
	if abs(ball.position.y - position.y) > 20:
		if ball.position.y > position.y:
			return 1
		else:
			return -1
	else:
		return 0

Sobre la pregunta de como hacer mas complicado el juego

Con las condiciones:

  • Player 400
  • Ball y Rival 600
  • Paleta 160 px
  • Diferencia de altura 25 para que se mueva la paleta Rival

El resultado es que la paleta rival empieza a moverse cuando la pelota esta 25 por arriba/debajo del centro(posicion) del Nodo

No es dificil responder, pero tampoco es tan facil 鈥渉acerle puntos鈥

Se podria disminuir el margen de 25 y/o aumentar la velocidad de la pelota y lapaleta Rival. Aumentar las velocidades conforme pasa el tiempo.

Otra opcion que vi, aunque no estoy seguro

Me parecio notar que la escena Player tiene el centro del Nodo en la esquina superior izquierda de los objetos (ColorRect y CollisionShape) y no en el centro de estos.

Esto provoca una demora en el arranque de la paleta rival cuando la pelota se mueve hacia arriba, ya que espera a que la paleta este 25 px por encima para empezar a moverse.
De esta manera es mas facil hacer puntos si buscas que la pelota rebote hacia arriba.
Teniendo esto como referencia, podriamos usar 2 margenes distintos y que de manera aleatoria la paleta se mueva mas rapido hacia arriba que hacia abajo o al reves. Para confundir al jugador.

Como yo odio los strings m谩gicos (en este caso 鈥淏all鈥) porque acopla el c贸digo a la escena recomiendo usar:

@export var ball:CharacterBody2D = null

en lugar de:

onready var ball = get_parent().find_node("Ball")

Eso s铆, tienes que asignarlo de forma 鈥渧isual鈥 en el editor as铆:

En este proyecto no hace falta, pero es una buena pr谩ctica, as铆 tus nodos ser谩n m谩s reutilizables.

Espero en un futuro poner una mejor IA, pues solo tengo mis ideas aunque no se como poner el c贸digo pero se trata de enga帽ar al jugador player entonces que se mueva en sentido opuesto a la pelota y posteriormente cuando este le de el golpe se mueva en sentido a la pelota para que le tiempo de poder pegarlo o a su ves calcular los golpes de pelota por 谩ngulos y este esperando la pelota jajajajaja NIEVEL MASTER de la IA.

Lista la IA comparto mi codigo 馃槂

Me gustar铆a agregar un metodo m铆o pero me falta aprender m谩s para programar.

Saludos! 馃槃
No me funciono la IA, asi que use el c贸digo del compa帽ero Santiago Palacio Vasquez.
Lo dejar茅 como mejora a futuro. (Quiz谩s por niveles)

Mi soluci贸n para el _get_direction

func _get_direction():
	var direction = Vector2.ZERO
	
	var y_diff = ball.position.y - position.y
	
	if abs(y_diff) > ai_reaction:
		direction.y = y_diff
		
	return direction.normalized()
Para Godot 4.2.1, se hace esto: * En la parte donde el profe dice lo de "onready", se debe escribir eso mismo pero con una arroba al inicio -> @onready * Esto es algo que hice yo porque no entend铆 bien como usar "move\_and\_slide()" en esta versi贸n de Godot, as铆 que yo us茅 "move\_and\_collide()" con tanto el Player como con el Oponente. Si lo haces, no olvides que hay que ponerle como argumento "direction \* speed \* delta". Si no pones ese delta, las barras se mover谩n a la velocidad de la luz. Espero que esto ayude <3

Para los que esten en Godot 4 y no puedan usar el move_and_slide(direction * speed) aqui les dejo mi codigo como referencia para que el oponente se mueva, tambien le agregue que el oponente se pueva solo cuando la pelota este a mitad del tablero y que no se mueva si la pelota le pasa.

extends CharacterBody2D

var speed = 620
var ball

func _ready():
	ball = get_parent().find_child("Ball")


func _physics_process(delta):
	if ball.position.x < 960 and ball.position.x > position.x:
		var direction = Vector2(0, _get_direction())
		velocity = direction * speed
		
		move_and_slide()


func _get_direction():
	if abs(ball.position.y - position.y) > 5:
		if ball.position.y > position.y:
			return 1
			
		else:
			return -1
		
	else:
		return 0

Por cierto en mi juego quise poner el oponente a la izquierda y el jugador a la derecha, en caso de tenerlo como en la clase solo deberian modificar la linea que dice 鈥渋f ball.position.x < 960 and ball.position.x > position.x鈥

Estuve renegando un poquitin tratando de deducir como adaptar esto al codigo de Godot 4. Resulta que find\_node fue removido, ahora se usa find\_child jaja. En fin. Aca esta mi codigo, le agregue un multiplicador de velocidad porque sino la partida no termina nunca. Y tambien hice una reformulacion de algo que hizo un compa帽ero para que la maquina solo se mueva si la pelota esta en su mitad del campo. extends CharacterBody2D var speed = 500 var is\_moving = false func \_ready(): randomize() velocity.x =\[-1,1]\[randi() % 2 ] \* speed velocity.y =\[-0.8,0.8]\[randi() % 2 ] \* speed is\_moving = true func \_physics\_process(delta): if is\_moving: var collide = move\_and\_collide(velocity \* delta) if collide: velocity.x = velocity.x \* 1.05 velocity.y = velocity.y \* 1.02 velocity = velocity.bounce(collide.get\_normal())
Postee el de la pelota jaja, este es el de la maquina, version Godot 4. `extends CharacterBody2D` `var speed = 600` `var ball` `var direction = 0` `func _ready() -> void:` ` ``ball = get_parent().find_child("Ball")` `func _physics_process(delta: float):` ` ``if ball.position.x > get_viewport_rect().size.x / 2 :` ` `` ``direction = Vector2(0, _get_direction())` ` `` ``velocity = direction * speed` ` `` ``move_and_slide()` `func _get_direction():` ` ``if abs(ball.position.y - position.y) > 25:` ` `` ``if ball.position.y > position.y:` ` `` `` ``return 1` ` `` ``else: ` ` `` `` ``return -1` ` ``else: ` ` `` ``return 0`

Para los que est茅n usando godot 4, en vez de poner 鈥渙nready鈥 directamente antes de la variable, ahora se pone 鈥淍onready鈥 por lo que la l铆nea de c贸digo quedar铆a de la siguiente forma:

@onready var ball = get_parent().get_node("Ball")

Siguiendo la idea de la compa帽era Andrea Stephania Garcia Castillo lo que hice fue agregar su condicional y juntarle el valor que tenemos cuando la pelota se dirije al enemigo, quedar铆a algo as铆鈥

func _physics_process(delta):
	if ball.direction.x > 0 and ball.position.x > 960: 
		var direction = Vector2(0, _get_direction())
		move_and_slide(direction * speed)