Kann ChatGPT einen Spieler programmieren, der sich wie in Pokémon Rot bewegt?
Ich habe mich heute kritisch mit dem Thema AI in der Spieleentwicklung mit #Godot auseinander gesetzt. Dafür habe ich das bekannte Tool ChatGPT verwendet.
Aufgabe: Schreibe eine Spieler Klasse in GDScript, die den Spieler so bewegt, wie in der roten Pokemon Edition.
Das war natürlich nicht der Wortlaut, den ich in die AI gespeist habe. Ich habe mir als Anfang eine allgemein gültige Spieler Klasse erstellen lassen.
Wenig überraschend hat diese auf Anhieb funktioniert und ließ den Spieler vertikal, horizontal und diagonal laufen. Not bad.
Wer die alten Pokemon Spiele kennt, weiß dass der Spieler aber nur vertikal & horizontal laufen kann und das auf einem ihm vorgegebenen Grid. Ich habe mich für meinen Test für ein gängiges 16px Grid entschieden. Trotz mehrfacher Versuche, konnte die AI mein Problem nicht lösen.
Sie verstrickte sich immer wieder in die selben Probleme. Zum Beispiel, dass, obwohl ich eine Richtungstaste nur kurz antippte, der Spieler gleich mehrere Felder voran preschte.
Natürlich sollte er trotzdem, bliebe die Richtungstaste gedrückt, mehrere Schritte gehen.
Das Ergebnis deckt sich daher mit meiner Meinung, die ich schon vor dem Test hatte: Die AI ChatGPT kann durchaus als Hilfestellung in der Programmierung genutzt werden; spart ggf. sogar Zeit um bekannte Probleme in Pseudocode zu skizzieren…
Mit anspruchsvolleren und spezifischeren Aufgaben, ist sie aber schnell überfordert. Den Job abluchsen wird sie mir so schnell also wohl nicht.
Hier folgt nun der funktionierende Code aus meiner eigenen Feder.
// Player.gd
extends KinematicBody2D
export var WALK_SPEED = 7.0
export var currentDirection = Vector2.DOWN
var TILE_SIZE: int = 16
var walkSpeed : float = WALK_SPEED
var initialPosition = Vector2(0, 0)
var inputDirection = Vector2(0, 1)
var isMoving = false
var percentMovedToNextTile = 0.0
func _ready():
initialPosition = position
inputDirection = currentDirection
func _physics_process(delta):
if isMoving == false:
processPlayerMovementInput()
if inputDirection != Vector2.ZERO:
move(delta, inputDirection)
else:
isMoving = false
func setDirection(direction: Vector2):
currentDirection = direction
func processPlayerMovementInput():
walkSpeed = WALK_SPEED
if inputDirection.y == 0:
inputDirection.x = int(Input.is_action_pressed("ui_right")) - int(Input.is_action_pressed("ui_left"))
if inputDirection.x == 0:
inputDirection.y = int(Input.is_action_pressed("ui_down")) - int(Input.is_action_pressed("ui_up"))
if inputDirection != Vector2.ZERO:
initialPosition = position
isMoving = true
var newcurrentDirection = currentDirection
if inputDirection.x < 0: newcurrentDirection = Vector2.LEFT elif inputDirection.x > 0:
newcurrentDirection = Vector2.RIGHT
elif inputDirection.y < 0: newcurrentDirection = Vector2.UP elif inputDirection.y > 0:
newcurrentDirection = Vector2.DOWN
if currentDirection != newcurrentDirection:
currentDirection = newcurrentDirection
return true
currentDirection = newcurrentDirection
return false
func move(delta, direction: Vector2):
var desiredStep: Vector2 = direction * TILE_SIZE / 2
percentMovedToNextTile += walkSpeed * delta
if percentMovedToNextTile >= 1.0:
position = initialPosition + (inputDirection * TILE_SIZE)
initialPosition = position # Update for `isMovingManually`
percentMovedToNextTile = 0.0
isMoving = false
else:
position = initialPosition + (inputDirection * TILE_SIZE * percentMovedToNextTile)