2019-02-10 01:39:11 +01:00
|
|
|
// Copyright 2019 The Ebiten Authors
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
2021-06-24 14:49:37 +02:00
|
|
|
//go:build example
|
2020-10-06 17:45:54 +02:00
|
|
|
// +build example
|
2019-02-10 01:39:11 +01:00
|
|
|
|
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"image/color"
|
|
|
|
"log"
|
|
|
|
"math/rand"
|
|
|
|
"time"
|
|
|
|
|
2020-10-03 19:35:13 +02:00
|
|
|
"github.com/hajimehoshi/ebiten/v2"
|
2019-02-10 01:39:11 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
screenWidth = 100
|
|
|
|
screenHeight = 50
|
|
|
|
screenSize = screenWidth * screenHeight
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
firePalette = []color.RGBA{
|
|
|
|
{R: 7, G: 7, B: 7, A: 255}, // 0
|
|
|
|
{R: 31, G: 7, B: 7, A: 255}, // 1
|
|
|
|
{R: 47, G: 15, B: 7, A: 255}, // 2
|
|
|
|
{R: 71, G: 15, B: 7, A: 255}, // 3
|
|
|
|
{R: 87, G: 23, B: 7, A: 255}, // 4
|
|
|
|
{R: 103, G: 31, B: 7, A: 255}, // 5
|
|
|
|
{R: 119, G: 31, B: 7, A: 255}, // 6
|
|
|
|
{R: 143, G: 39, B: 7, A: 255}, // 7
|
|
|
|
{R: 159, G: 47, B: 7, A: 255}, // 8
|
|
|
|
{R: 175, G: 63, B: 7, A: 255}, // 9
|
|
|
|
{R: 191, G: 71, B: 7, A: 255}, // 10
|
|
|
|
{R: 199, G: 71, B: 7, A: 255}, // 11
|
|
|
|
{R: 223, G: 79, B: 7, A: 255}, // 12
|
|
|
|
{R: 223, G: 87, B: 7, A: 255}, // 13
|
|
|
|
{R: 223, G: 87, B: 7, A: 255}, // 14
|
|
|
|
{R: 215, G: 95, B: 7, A: 255}, // 15
|
|
|
|
{R: 215, G: 95, B: 7, A: 255}, // 16
|
|
|
|
{R: 215, G: 103, B: 15, A: 255}, // 17
|
|
|
|
{R: 207, G: 111, B: 15, A: 255}, // 18
|
|
|
|
{R: 207, G: 119, B: 15, A: 255}, // 19
|
|
|
|
{R: 207, G: 127, B: 15, A: 255}, // 20
|
|
|
|
{R: 207, G: 135, B: 23, A: 255}, // 21
|
|
|
|
{R: 199, G: 135, B: 23, A: 255}, // 22
|
|
|
|
{R: 199, G: 143, B: 23, A: 255}, // 23
|
|
|
|
{R: 199, G: 151, B: 31, A: 255}, // 24
|
|
|
|
{R: 191, G: 159, B: 31, A: 255}, // 25
|
|
|
|
{R: 191, G: 159, B: 31, A: 255}, // 26
|
|
|
|
{R: 191, G: 167, B: 39, A: 255}, // 27
|
|
|
|
{R: 191, G: 167, B: 39, A: 255}, // 28
|
|
|
|
{R: 191, G: 175, B: 47, A: 255}, // 29
|
|
|
|
{R: 183, G: 175, B: 47, A: 255}, // 30
|
|
|
|
{R: 183, G: 183, B: 47, A: 255}, // 31
|
|
|
|
{R: 183, G: 183, B: 55, A: 255}, // 32
|
|
|
|
{R: 207, G: 207, B: 111, A: 255}, // 33
|
|
|
|
{R: 223, G: 223, B: 159, A: 255}, // 34
|
|
|
|
{R: 239, G: 239, B: 199, A: 255}, // 35
|
|
|
|
{R: 255, G: 255, B: 255, A: 255}, // 36
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
2020-04-12 12:12:57 +02:00
|
|
|
type Game struct {
|
2021-07-21 17:15:30 +02:00
|
|
|
pixels []byte
|
|
|
|
indices []byte
|
2020-04-12 12:12:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func NewGame() *Game {
|
2021-07-21 17:15:30 +02:00
|
|
|
indices := make([]byte, screenSize)
|
2019-02-10 01:39:11 +01:00
|
|
|
for i := screenSize - screenWidth; i < screenSize; i++ {
|
2021-07-21 17:15:30 +02:00
|
|
|
indices[i] = 36
|
2019-02-10 01:39:11 +01:00
|
|
|
}
|
2020-04-12 12:12:57 +02:00
|
|
|
return &Game{
|
2021-07-21 17:15:30 +02:00
|
|
|
pixels: make([]byte, screenSize*4),
|
|
|
|
indices: indices,
|
2020-04-12 12:12:57 +02:00
|
|
|
}
|
2019-02-10 01:39:11 +01:00
|
|
|
}
|
|
|
|
|
2020-04-12 12:12:57 +02:00
|
|
|
func (g *Game) updateFirePixels() {
|
2019-02-10 01:39:11 +01:00
|
|
|
for i := 0; i < screenWidth; i++ {
|
|
|
|
for j := 0; j < screenHeight; j++ {
|
|
|
|
idx := i + (screenWidth * j)
|
2020-04-12 12:12:57 +02:00
|
|
|
g.updateFireIntensityPerPixel(idx)
|
2019-02-10 01:39:11 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-12 12:12:57 +02:00
|
|
|
func (g *Game) updateFireIntensityPerPixel(currentPixelIndex int) {
|
2019-02-10 01:39:11 +01:00
|
|
|
below := currentPixelIndex + screenWidth
|
|
|
|
if below >= screenSize {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
d := rand.Intn(3)
|
2021-07-21 17:15:30 +02:00
|
|
|
newI := int(g.indices[below]) - d
|
2019-02-10 01:39:11 +01:00
|
|
|
if newI < 0 {
|
|
|
|
newI = 0
|
|
|
|
}
|
|
|
|
|
|
|
|
if currentPixelIndex-d < 0 {
|
|
|
|
return
|
|
|
|
}
|
2021-07-21 17:15:30 +02:00
|
|
|
g.indices[currentPixelIndex-d] = byte(newI)
|
2019-02-10 01:39:11 +01:00
|
|
|
}
|
|
|
|
|
2020-04-12 12:12:57 +02:00
|
|
|
func (g *Game) renderFire() {
|
2021-07-21 17:15:30 +02:00
|
|
|
for i, v := range g.indices {
|
2019-02-10 01:39:11 +01:00
|
|
|
p := firePalette[v]
|
2021-07-21 17:15:30 +02:00
|
|
|
g.pixels[i*4] = p.R
|
|
|
|
g.pixels[i*4+1] = p.G
|
|
|
|
g.pixels[i*4+2] = p.B
|
|
|
|
g.pixels[i*4+3] = p.A
|
2019-02-10 01:39:11 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-04 10:42:54 +02:00
|
|
|
func (g *Game) Update() error {
|
2020-04-12 12:12:57 +02:00
|
|
|
g.updateFirePixels()
|
|
|
|
return nil
|
|
|
|
}
|
2019-02-10 01:39:11 +01:00
|
|
|
|
2020-04-12 12:12:57 +02:00
|
|
|
func (g *Game) Draw(screen *ebiten.Image) {
|
|
|
|
g.renderFire()
|
2021-07-21 17:15:30 +02:00
|
|
|
screen.ReplacePixels(g.pixels)
|
2020-04-12 12:12:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
|
|
|
|
return screenWidth, screenHeight
|
2019-02-10 01:39:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
rand.Seed(time.Now().UnixNano())
|
|
|
|
|
2020-04-12 12:12:57 +02:00
|
|
|
ebiten.SetWindowSize(screenWidth*6, screenHeight*6)
|
|
|
|
ebiten.SetWindowTitle("Doom Fire (Ebiten Demo)")
|
|
|
|
if err := ebiten.RunGame(NewGame()); err != nil {
|
2019-02-10 01:39:11 +01:00
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|