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 0000000..08517e8 Binary files /dev/null and b/static/images/pong-title.png differ