Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Game Programming With Godot

Download as pdf or txt
Download as pdf or txt
You are on page 1of 40

Game programming with

Godot
foss-gbg 2019-10 // Johan Thelin
What we will look at today

● Intro to the editor


● 2D and 3D games
● Intro to VR using Godot
● Intro to deployment using Godot
Intro
● I encourage you to code along!
● All examples can be found at https://github.com/e8johan/godot-tutorial .

● Assets the raw assets


● 01_flippable 2D intro example
● 02_platformer 2D platformer
● 02b_platformer_animated 2D platformer with animated hero
● 03_on_a_roll 3D example
● 04_on_a_roll_vr 3D VR example
Bio
Johan Thelin - co-founder of Kuro Studio

Autoliv → XDIN → Bitsim → Trolltech → Pelagicore → Kuro

I’ve done lots and lots of embedded devices with Qt, Linux, etc

Absolutely zero game programming experience :-)


What is Godot
Modern game engine

Visual editor

Open source

www.godotengine.org
Getting Godot
● A ~25MB download from https://godotengine.org/download
● Available for Linux, Windows, MacOS and Server

● The download contains the executable - just download and run


● … or use your distro’s package manager

● Today, we will focus on the standard version - no C# or other external deps


● I’m using version 3.1
The Editor
● Main view
○ 2D
○ 3D
○ Script
● File system
○ res://
● Scene
● Inspector
Let’s create!
● You will learn about
○ Nodes
○ Scenes
○ Scripts

● Create nodes
○ Node2D
■ Sprite x2
■ Area2D
● CollisionShape2D
The flipper script
extends Node2D

onready var front = $Front


onready var back = $Back

func _on_Area2D_input_event(viewport, event, shape_idx):


if event is InputEventMouseButton:
if event.is_pressed() and event.button_index == BUTTON_LEFT:
front.visible = !front.visible
back.visible = !front.visible
GDScript
● Very pythonesque - but not Python
● Can do typing - will improve performance
○ var x : int = 10
○ var y := calculate_something()
○ func double_it(value : int) -> int:
○ Enums are problematic

● Resources I go to for help


○ https://docs.godotengine.org/en/3.1/getting_started/scripting/gdscript/gdscript_basics.html
○ https://www.gdquest.com/open-source/guidelines/godot-gdscript/
● There is more - my code is far from stylistically correct or efficient
Creating a world
● Create a world with two cards, and a UI

● Update UI based on state


Signal and setter for the Card
extends Node2D

signal flipped_changed
var flipped : bool = false setget set_flipped

onready var front = $Front


onready var back = $Back

func _on_Area2D_input_event(viewport, event, shape_idx):


if event is InputEventMouseButton:
if event.is_pressed() and event.button_index == BUTTON_LEFT:
set_flipped(front.visible)

func set_flipped(f : bool) -> void:


front.visible = !f
back.visible = f
flipped = f
emit_signal("flipped_changed")
The World script
extends Node2D

func _ready():
$Label.text = str(no_of_flipped_cards())
$Card.connect("flipped_changed", self, "_on_flipped_changed")
$Card2.connect("flipped_changed", self, "_on_flipped_changed")

func _on_flipped_changed():
$Label.text = str(no_of_flipped_cards())

func no_of_flipped_cards() -> int:


var res : int = 0
if $Card.flipped:
res += 1
if $Card2.flipped:
res += 1
return res
Finding children - the smarter way
func _find_all_cards() -> Array:
var res : Array = []
var children : = self.get_children()
for child in children:
if child.is_in_group("cards"):
res.append(child)
return res

From https://github.com/e8johan/supermemory/blob/master/table.gd#L210
Platformer time!
● The game plan:
○ Create tile set
○ Create tile map
○ Create character
○ Jump around

● You will learn about


○ Tiled 2D worlds
○ 2D movement
○ Animations
○ Input events
The tile set
● 2D Scene - “Tiles”
○ Sprite
○ StaticBody2D
○ CollisionShape2D
○ RectangleShape2D
○ Extent

● Scene → Convert to… → TileSet...


The tile map
● 2D Scene - World
● TileMap
○ Cell size
● Sprite - for bg
Enter: the hero!
● KinematicBody2D
○ CollisionShape2D
■ CapsuleShape
○ Sprite

● CaptainCode!
Importing
Enter into the World
Jump around!
extends KinematicBody2D func _physics_process(delta):
get_input()
export (int) var speed = 240 velocity.y += gravity * delta
export (int) var jump_speed = -320 velocity = move_and_slide(velocity, Vector2.UP)
export (int) var gravity = 600 if Input.is_action_just_pressed("jump"):
if is_on_floor():
var velocity = Vector2.ZERO velocity.y = jump_speed

func get_input():
velocity.x = 0
if Input.is_action_pressed("ui_right"):
velocity.x += speed
if Input.is_action_pressed("ui_left"):
velocity.x -= speed http://kidscancode.org/godot_recipes/2d/platform_character/
What is an input?
Animations!
● Change Captain Code from Sprite to AnimatedSprite
● New SpriteFrames in Frames
● Add the following:
○ Idle
○ Run
○ Jump
Play the right animation
func get_input() -> int: func _physics_process(delta):
var res : int = 0 var dir := get_input()
velocity.x = 0 if dir > 0:
if Input.is_action_pressed("ui_right"): $Sprite.flip_h = false
velocity.x += speed $Sprite.play("walk")
res = 1 elif dir < 0:
if Input.is_action_pressed("ui_left"): $Sprite.play("walk")
velocity.x -= speed $Sprite.flip_h = true
res = -1 else:
return res $Sprite.play("idle")

if is_on_floor():
...
else:
$Sprite.play("jump")
What about 3D?
● You will learn about:
○ GridMaps and Mesh libraries
○ Basic lights and shadows
○ 3D collisions
Meshes and Maps
● MeshInstance
○ Mesh: CubeMesh
○ Create Convex Static Body

● Material
● SpatialMaterial
● Albedo
A World
● New 3D Scene - World
○ GridMap
○ Mesh Library = meshes.tres

● Don’t forget the Camera!


A movable sphere
● KinematicBody - Player
○ MeshInstance
○ CollisionShape

● Setup inputs

● Add to world
Movement script
extends KinematicBody if Input.is_action_pressed("left"):
velocity.x = -SPEED
var velocity : Vector3 = Vector3.ZERO elif Input.is_action_pressed("right"):
velocity.x = SPEED
const SPEED = 10 else:
const GRAVITY = 10 velocity.x = 0

func _physics_process(delta): velocity = move_and_slide(velocity, Vector3.UP)


velocity.y -= GRAVITY * delta
if Input.is_action_pressed("forward"):
velocity.z = -SPEED
elif Input.is_action_pressed("back"):
velocity.z = SPEED
else:
velocity.z = 0
On a roll!
Various Bodies
● StaticBody
○ Static, does not move
○ Perfect for walls and such
● KinematicBody
○ Can be moved about
○ Commonly used for characters
● RigidBody
○ Simulates newtonian physics
Let’s add some light
● DirectionalLight
● Enable shadows
Let’s make the ball jump
● Add input “jump”
● Add to _physics_process:

if is_on_floor():
if Input.is_action_just_pressed("jump"):
velocity.y = JUMP
Going VR
● Godot comes with AR and VR support
● I’ve played around with SteamVR (Oculus DK2) and Google Cardboard

● Supports cameras and wands


Setting up VR
● Replace Camera node with ARVROrigin and ARVRCamera

● Initialize sub-system:

func _ready():
var interface = ARVRServer.find_interface("Native mobile")
if interface and interface.initialize():
get_viewport().arvr = true

● Preferably do some error handling :-)


Try it!
Deploying Godot projects
● Editor
○ Manage Export Templates
● Project
○ Export

● Requires some setup


○ Android
○ iOS
○ Windows Universal
● And you can build your own!
Deploying Godot projects
Android development
Things we didn’t learn
● Sound
● Dynamic instantiation
● 3D assets from Blender
● Skeleton animations
● Shaders Thank you!
● Path finding
● C# bindings
● GDNative, i.e. rust, C++, and beyond
● Setting up an Android target
● Setting up an iOS target
● And much, much more...

You might also like