From ee5f0910210e1c752a8706acded78e224e3566ed Mon Sep 17 00:00:00 2001 From: Yami Odymel Date: Sun, 30 Oct 2016 00:51:37 +0800 Subject: [PATCH] Created Screen, colors and the squares (markdown) --- Screen,-colors-and-the-squares.md | 175 ++++++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 Screen,-colors-and-the-squares.md diff --git a/Screen,-colors-and-the-squares.md b/Screen,-colors-and-the-squares.md new file mode 100644 index 0000000..1e79e48 --- /dev/null +++ b/Screen,-colors-and-the-squares.md @@ -0,0 +1,175 @@ +You've already learned things about how to make a basic game with Ebiten in the last tutorial, but that cannot be count as an actual game (*Because it can only shows the text*), we would need to learn more things about the screen before we make a real game, and that's what we'll talk about in this chapter. + +The game screen is **the most important place** in the game (*Of course*), **it displays everything you can see**, and the screen is always been refreshing but the speed is too fast so **it might have been refreshed million times before you've noticed**. + +Let's continue the example from the last tutorial, I've brought it to here. By the way, *I've added some comments for you :)* + +```go +package main + +import ( + "github.com/hajimehoshi/ebiten" + "github.com/hajimehoshi/ebiten/ebitenutil" +) + +func update(screen *ebiten.Image) error { + // Display the text though the debug function + ebitenutil.DebugPrint(screen, "Our first game in Ebiten!") + + return nil +} + +func main() { + // Initialize Ebiten, and loop the update() function + ebiten.Run(update, 320, 240, 2, "Hello world!") +} +``` + +Remember the code above will display something like this right? + +![](http://i.imgur.com/In5N0Ck.png) + +Hmmm... It seems a little bit boring, how about **filling the screen with some colors**? + +# Color struct + +Before you color your game screen, **you would've to create a color struct**, it's quite simple, you might already heard about the **Hex color** (for example: `#FF0000`) if you have experience with the **photo editor** or the **webpage design software** before. + +You will need to **import the `image/color` package** to create the color struct by replacing the `import` section of your code to this: + +```go +import ( + "github.com/hajimehoshi/ebiten" + "github.com/hajimehoshi/ebiten/ebitenutil" + "image/color" +) +``` + +Great! And it's time to create a color, how about... a red color? **The hex of the red is `#FF0000`**, so it will be `0xff, 0x00, 0x00` in our code, and it looks like this (You don't have to edit the last `0xff`): + +```go +color.NRGBA{0xff, 0x00, 0x00, 0xff} +``` + +Alright, now you know how to create a new color, and it's time to paint your game screen. + +# Fill the screen with the color + +There's a `Fill(clr color.Color)` function for the screen in Ebiten, it used to fill the screen with a color, and **you will need to pass a `color.Color` data type to the function**, **that's exactly what our color struct returns**! So what are we waiting for? + +Remember the `update()` function? Yeah, the function which keep been calling by Ebiten, and we'll paint the screen in the function. + +```go +func update(screen *ebiten.Image) error { + + // Fill the screen with #FF0000 color + screen.Fill(color.NRGBA{0xff, 0x00, 0x00, 0xff}) + + // Display the text though the debug function + ebitenutil.DebugPrint(screen, "Our first game in Ebiten!") + + return nil +} +``` + +You would've to care about **the priority of the codes above**, you will need to **fill the color before you display the text**, otherwise the text will be covered by the color (*So you couldn't see the text*). + +And save your file, run `go run ./main.go` in your terminal, you'll see the following result: + +![](http://i.imgur.com/qMhWeY3.png) + +# Creating squares + +In the next few steps, we'll create some squares, so the game will be more *game-like*. The squares won't be able to move at least now, but trust me, **in the next few chapters it will be able to** ;). + +## Squares are just *images* + +**There're actually no squares in Ebiten**. **Everything is an image** (*Includes the screen, it's just bigger*), so what we'll do next, is **just creating a new image**, and make it looks like a square. + +## Fill the new image with the color + +Like we said before, the **squares were just images**, You can **create a new image** by using `ebiten.NewImage(width, height int, filter Filter)` in Ebiten, here are the values that you'll need to provide to the function: + +* `width` is the **width** of the new image with the pixels. +* `height` is the **height** of the new image with the pixels. +* `filter` is the filter for rendering the image, we won't use it at this chapter, so just do what we do and it'll be okay. + +In the following example, we'll **create an 16x16 image**, it will **look like a common square**, and the **image will be saved into the `square` variable**, so we can use it later, it's not matter about how you named the variables, just remember **you can only name the variables with alphanumeric**. + +```go +// Create an 16x16 image +square, _ := ebiten.NewImage(16, 16, ebiten.FilterNearest) + +// Fill the square with the white color +square.Fill(color.White) +``` + +In the end of the code, we used a new way to color our new image with the `color.White` color. You won't want to create a transparent image, will you? + +You might wondering about what is `color.White`, you can actually found it in the `image/color` package, the package provided two default colors, which are *BLACK* (`color.Black`) and *WHITE* (`color.White`). + +## Reposition and render the image to the game screen + +**You will need to render the new image to the main screen** once you've created it, otherwise it won't be displayed on the screen, but before you do it, you will also need to create a "render option struct" **which's named as `DrawImageOptions{}`**, **it used to tell Ebiten HOW should the image be drew on the screen**, we'll talk about it later, and right now, we can leave it as blank. + +Here's the fully example, we'll explain it later. The examples above were be done in the `update()` function, so let's see what should your `update()` function be this time. + +```go +func update(screen *ebiten.Image) error { + + // Fill the screen with #FF0000 color + screen.Fill(color.NRGBA{0xff, 0x00, 0x00, 0xff}) + + // Display the text though the debug function + ebitenutil.DebugPrint(screen, "Our first game in Ebiten!") + + // Create an 16x16 image + square, _ := ebiten.NewImage(16, 16, ebiten.FilterNearest) + + // Fill the square with the white color + square.Fill(color.White) + + // Create an empty option struct + opts := &ebiten.DrawImageOptions{} + + // Draw the square image to the screen with an empty option + screen.DrawImage(square, opts) + + return nil +} +``` + +`DrawImage(image *Image, options *DrawImageOptions)` is the function that draws the image to the screen, it's simple to use. **You will need to pass the new image which will be rendered on the screen to the first parameter**, and **the second one is the render option struct which we created above**, and that's it, simple, right? + +Now run your game with `go run ./main.go` command in your terminal after you saved it. + +![](http://i.imgur.com/IdFYBoH.png) + +Oops! Our text is covered by the new image! We'll need to **set the position of the image** to avoid the such issue. + +# Image transforming + +There's **no position configuration** in Ebiten, but you can **get the same result by transforming your images**, there're **many ways to transform** your images in Ebiten, but we'll only talk the basic `x`, `y` **position translate** in this chapter. + +What we need is to **add the `translate` effect to the `option struct`** by using `Translate(tx, ty float64)` function, `float64` is the **floating point data type**, and here're the two parameters that you'll need to pass to the function: + +* `tx` Is the distance **from the left**, it's also called as the **x offset**. +* `ty` Is the distance **from the top**, and it's also called as the **y offset**. + +So right now, let's add another code to tell the render function that **we want to translate the new image while rendering it**. + +```go +// The previous empty option struct +opts := &ebiten.DrawImageOptions{} + +// Add the Translate effect to the option struct. +opts.GeoM.Translate(64, 64) +``` + +Save your file, execute your game, and you'll see the new image is 64 pixels far from the top and the left of the screen. + +![](http://i.imgur.com/ChN4qp9.png) + +By the way, you can also translate each of your image to get the following result. + +![](http://i.imgur.com/BVh8SO6.png) \ No newline at end of file