From 5f23dd076137a6f334fc42d4508533b994851c85 Mon Sep 17 00:00:00 2001 From: Evan Hemsley Date: Sun, 9 Jun 2019 18:59:57 -0700 Subject: [PATCH] title tutorial --- content/pong/polish/_index.md | 2 +- content/pong/polish/title.md | 166 ++++++++++++++++++++++++++++++++++ static/images/pong-title.png | Bin 0 -> 77260 bytes 3 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 content/pong/polish/title.md create mode 100644 static/images/pong-title.png diff --git a/content/pong/polish/_index.md b/content/pong/polish/_index.md index e4b37ff..c05a52b 100644 --- a/content/pong/polish/_index.md +++ b/content/pong/polish/_index.md @@ -1,5 +1,5 @@ --- -title: "Polish" +title: "Finishing Touches" date: 2019-06-08T14:44:31-07:00 weight: 5000 --- diff --git a/content/pong/polish/title.md b/content/pong/polish/title.md new file mode 100644 index 0000000..9f6ac6b --- /dev/null +++ b/content/pong/polish/title.md @@ -0,0 +1,166 @@ +--- +title: "Title" +date: 2019-06-09T16:51:13-07:00 +weight: 20 +--- + +It would be nice to have a title screen. Let's make that happen. + +I would like us to have a concept of game state. The title menu is a pretty distinct thing from the game itself so it feels nicer to have it be self contained instead of managing extra state in the game world. + +Let's create a new class in **game/state.ts**: + +```ts +export abstract class State { + public abstract load(): void; + public abstract update(dt: number): void; + public abstract draw(): void; +} +``` + +Let's create a new folder, **game/states**, and put **game.ts** in there. Let's also make it inherit from State: + +```ts +export class Game extends State { +``` + +Let's make a new State called Title. It doesn't need to do much - just display the game title and a prompt for the player to start the game. + +```ts +import { State } from "game/state"; + +export class Title extends State { + private title_font: Font; + private title_text: Text; + + private play_font: Font; + private play_text: Text; + + public load() { + this.title_font = love.graphics.newFont("game/assets/fonts/Squared Display.ttf", 128); + this.title_text = love.graphics.newText(this.title_font, "Encompass Pong"); + + this.play_font = love.graphics.newFont("game/assets/fonts/Squared Display.ttf", 32); + this.play_text = love.graphics.newText(this.play_font, "Press Space"); + } + + public update() {} + + public draw() { + love.graphics.draw( + this.title_text, + 640, + 240, + 0, + 1, + 1, + this.title_text.getWidth() * 0.5, + this.title_text.getHeight() * 0.5, + ); + + love.graphics.draw( + this.play_text, + 640, + 480, + 0, + 1, + 1, + this.play_text.getWidth() * 0.5, + this.play_text.getHeight() * 0.5, + ); + } +} +``` + +Now in **main.ts** we can put code to handle our states. + +```ts +let menu: Title; +let game: Game; +let current_state: State; + +love.load = () => { + ... + + menu = new Menu(); + menu.load(); + + game = new Game(); + game.load(); + + current_state = menu; +}; + +love.update = (dt) => { + current_state.update(dt); + if (current_state === menu) { + if (love.keyboard.isDown("space")) { + current_state = game; + } + } +}; + +love.draw = () => { + current_state.draw(); + + ... +} +``` + +The final result of **main.ts** should look like this. + +```ts +declare global {let PROF_CAPTURE: boolean; } +PROF_CAPTURE = false; // set this to true to enable profiling + +import * as jprof from "encompass-jprof"; +import { State } from "game/state"; +import { Game } from "game/states/game"; +import { Title } from "game/states/title"; + +let menu: Title; +let game: Game; +let current_state: State; + +love.load = () => { + love.window.setMode(1280, 720, {vsync: false, msaa: 2}); + love.math.setRandomSeed(os.time()); + love.mouse.setVisible(false); + + menu = new Title(); + menu.load(); + + game = new Game(); + game.load(); + + current_state = menu; +}; + +love.update = (dt) => { + current_state.update(dt); + if (current_state === menu) { + if (love.keyboard.isDown("space")) { + current_state = game; + } + } +}; + +love.draw = () => { + current_state.draw(); + + love.graphics.setBlendMode("alpha"); + love.graphics.setColor(1, 1, 1, 1); + love.graphics.print("Current FPS: " + tostring(love.timer.getFPS()), 10, 10); +}; + +love.quit = () => { + jprof.write("prof.mpack"); + return false; +}; +``` + +Let's try it! + +![pong title](/images/pong-title.png) + +Nice! diff --git a/static/images/pong-title.png b/static/images/pong-title.png new file mode 100644 index 0000000000000000000000000000000000000000..08517e824d1ebf2e68d5b5637428bf918a7f706c GIT binary patch literal 77260 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 literal 0 HcmV?d00001